text:
package org.apache.ofbiz.pricat.sample;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.poi.POIXMLException;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.commons.fileupload.FileItem;
import org.apache.ofbiz.pricat.AbstractPricatParser;
import org.apache.ofbiz.htmlreport.InterfaceReport;
import org.apache.ofbiz.order.finaccount.FinAccountHelper;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.transaction.GenericTransactionException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ServiceUtil;

/**
 * Sample pricat excel parser.
 *
 */
public class SamplePricatParser extends AbstractPricatParser {

    public static final String module = SamplePricatParser.class.getName();

    public static final Map<String, List<Object[]>> ColNamesList = UtilMisc.toMap("V1.1", genExcelHeaderNames("V1.1"));

    public static final int headerRowNo = 4;

    private List<String> headerColNames = new ArrayList<String>();

    public SamplePricatParser(LocalDispatcher dispatcher, Delegator delegator, Locale locale, InterfaceReport report, Map<String, String[]> facilities, File pricatFile, GenericValue userLogin) {
        super(dispatcher, delegator, locale, report, facilities, pricatFile, userLogin);
    }

    /**
     * Parse pricat excel file in xlsx format.
     *
     */
    public void parsePricatExcel(boolean writeFile) {
        XSSFWorkbook workbook = null;
        try {
            // 1. read the pricat excel file
            FileInputStream is = new FileInputStream(pricatFile);

            // 2. use POI to load this bytes
            report.print(UtilProperties.getMessage(resource, "ParsePricatFileStatement", new Object[] { pricatFile.getName() }, locale), InterfaceReport.FORMAT_DEFAULT);
            try {
                workbook = new XSSFWorkbook(is);
                report.println(UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
            } catch(IOException e) {
                report.println(e);
                report.println(UtilProperties.getMessage(resource, "PricatSuggestion", locale), InterfaceReport.FORMAT_ERROR);
                return;
            } catch(POIXMLException e) {
                report.println(e);
                report.println(UtilProperties.getMessage(resource, "PricatSuggestion", locale), InterfaceReport.FORMAT_ERROR);
                return;
            }

            // 3. only first sheet will be parsed
            // 3.1 verify the file has a sheet at least
            formatter = new HSSFDataFormatter(locale);
            isNumOfSheetsOK(workbook);

            // 3.2 verify the version is supported
            XSSFSheet sheet = workbook.getSheetAt(0);
            if (!isVersionSupported(sheet)) {
                return;
            }

            // 3.3 get currencyId
            existsCurrencyId(sheet);

            // 3.4 verify the table header row is just the same as column names, if not, print error and return
            if (!isTableHeaderMatched(sheet)) {
                return;
            }

            // 3.5 verify the first table has 6 rows at least
            containsDataRows(sheet);

            if (UtilValidate.isNotEmpty(errorMessages)) {
                report.println(UtilProperties.getMessage(resource, "HeaderContainsError", locale), InterfaceReport.FORMAT_ERROR);
                return;
            }

            // 4. parse data
            // 4.1 parse row by row and store the contents into database
            parseRowByRow(sheet);
            if (UtilValidate.isNotEmpty(errorMessages)) {
                report.println(UtilProperties.getMessage(resource, "DataContainsError", locale), InterfaceReport.FORMAT_ERROR);
                if (writeFile) {
                    sequenceNum = report.getSequenceNum();
                    writeCommentsToFile(workbook, sheet);
                }
            }

            // 5. clean up the log files and commented Excel files
            cleanupLogAndCommentedExcel();
        } catch (IOException e) {
            report.println(e);
            Debug.logError(e, module);
        } finally {
            if (UtilValidate.isNotEmpty(fileItems)) {
                // remove tmp files
                FileItem fi = null;
                for (int i = 0; i < fileItems.size(); i++) {
                    fi = fileItems.get(i);
                    fi.delete();
                }
            }
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    Debug.logError(e, module);
                }
            }
        }
    }

    public boolean existsCurrencyId(XSSFSheet sheet) {
        report.print(UtilProperties.getMessage(resource, "StartCheckCurrencyId", locale), InterfaceReport.FORMAT_NOTE);
        XSSFCell currencyIdCell = sheet.getRow(2).getCell(1);
        currencyId = currencyIdCell.getStringCellValue().trim().toUpperCase();
        if (UtilValidate.isEmpty(currencyId)) {
            String errorMessage = UtilProperties.getMessage(resource, "CurrencyIdRequired", locale);
            report.println(errorMessage, InterfaceReport.FORMAT_ERROR);
            errorMessages.put(new CellReference(currencyIdCell), errorMessage);
            return false;
        } else {
            try {
                GenericValue currencyUom = delegator.findOne("Uom", UtilMisc.toMap("uomId", currencyId), false);
                if (!"CURRENCY_MEASURE".equals(currencyUom.getString("uomTypeId"))) {
                    String errorMessage = UtilProperties.getMessage(resource, "CurrencyIdNotCurrency", new Object[] {currencyId}, locale);
                    report.println(errorMessage, InterfaceReport.FORMAT_ERROR);
                    errorMessages.put(new CellReference(currencyIdCell), errorMessage);
                    return false;
                }
            } catch(GenericEntityException e) {
                String errorMessage = UtilProperties.getMessage(resource, "CurrencyIdNotFound", new Object[] {currencyId}, locale);
                report.println(errorMessage, InterfaceReport.FORMAT_ERROR);
                errorMessages.put(new CellReference(currencyIdCell), errorMessage);
                return false;
            }
            report.print(UtilProperties.getMessage(resource, "CurrencyIdIs", new Object[] {currencyId}, locale), InterfaceReport.FORMAT_NOTE);
            report.println(" ... " + UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        }
        return true;
    }

    public void parseRowByRow(XSSFSheet sheet) {
        int rows = sheet.getPhysicalNumberOfRows();
        List<Object[]> colNames = ColNamesList.get(pricatFileVersion);
        int colNumber = colNames.size();

        int emptyRowStart = -1;
        int emptyRowEnd = -1;
        for (int i = headerRowNo + 1; i < rows; i++) {
            XSSFRow row = sheet.getRow(i);
            if (UtilValidate.isEmpty(row) || isEmptyRow(row, colNumber, false)) {
                if (emptyRowStart == -1) {
                    report.print("(" + (i + 1) + ") ", InterfaceReport.FORMAT_NOTE);
                    emptyRowStart = i;
                } else {
                    emptyRowEnd = i;
                }
                continue;
            } else {
                if (emptyRowStart != -1) {
                    if (emptyRowEnd != -1) {
                        report.print(" - (" + (emptyRowEnd + 1) + ") ", InterfaceReport.FORMAT_NOTE);
                    }
                    report.print(UtilProperties.getMessage(resource, "ExcelEmptyRow", locale), InterfaceReport.FORMAT_NOTE);
                    report.println(" ... " + UtilProperties.getMessage(resource, "skipped", locale), InterfaceReport.FORMAT_NOTE);
                    emptyRowStart = -1;
                    emptyRowEnd = -1;
                }
            }
            report.print("(" + (i + 1) + ") ", InterfaceReport.FORMAT_NOTE);
            List<Object> cellContents = getCellContents(row, colNames, colNumber);
            try {
                if (parseCellContentsAndStore(row, cellContents)) {
                    report.println(" ... " + UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
                } else {
                    report.println(" ... " + UtilProperties.getMessage(resource, "skipped", locale), InterfaceReport.FORMAT_NOTE);
                }
            } catch (GenericTransactionException e) {
                report.println(e);
            }
        }
        if (emptyRowEnd != -1) {
            report.print(" - (" + (emptyRowEnd + 1) + ") ", InterfaceReport.FORMAT_NOTE);
            report.print(UtilProperties.getMessage(resource, "ExcelEmptyRow", locale), InterfaceReport.FORMAT_NOTE);
            report.println(" ... " + UtilProperties.getMessage(resource, "skipped", locale), InterfaceReport.FORMAT_NOTE);
        }
    }

    /**
     * Check data according to business logic. If data is ok, store it.
     *
     * @param row
     * @param cellContents
     * @return
     * @throws GenericTransactionException
     */
    public boolean parseCellContentsAndStore(XSSFRow row, List<Object> cellContents) throws GenericTransactionException {
        if (UtilValidate.isEmpty(cellContents)) {
            return false;
        }
        switch(pricatFileVersion) {
            case "V1.1":
            default:
                return parseCellContentsAndStoreV1_X(row, cellContents);
        }
    }

    private boolean parseCellContentsAndStoreV1_X(XSSFRow row, List<Object> cellContents) throws GenericTransactionException {
        if (UtilValidate.isEmpty(cellContents)) {
            return false;
        }
        // 1. check if facilityId is in the facilities belong to the user, or if the name is correct for the id
        String facilityName = (String) getCellContent(cellContents, "Facility Name");
        String facilityId = (String) getCellContent(cellContents, "FacilityId");
        if (!isFacilityOk(row, facilityName, facilityId))
            return false;

        // 2. get productCategoryId
        String ownerPartyId = facilities.get(facilityId)[1];
        String productCategoryId = getProductCategoryId(cellContents, ownerPartyId);

        // 3. get productFeatureId of brand
        String brandName = (String) getCellContent(cellContents, "Brand");
        String brandId = getBrandId(brandName, ownerPartyId);
        if (UtilValidate.isEmpty(brandId)) {
            return false;
        }

        // 4. get productId from brandId, model name
        String modelName = (String) getCellContent(cellContents, "Style No");
        String productName = (String) getCellContent(cellContents, "Product Name");
        BigDecimal listPrice = (BigDecimal) getCellContent(cellContents, "List Price");
        String productId = getProductId(row, brandId, modelName, productName, productCategoryId, ownerPartyId, listPrice);
        if (UtilValidate.isEmpty(productId) || UtilValidate.isEmpty(listPrice)) {
            return false;
        }

        // 5. update color and size if necessary
        String color = (String) getCellContent(cellContents, "Color");
        if (UtilValidate.isEmpty(color) || UtilValidate.isEmpty(color.trim())) {
            color = defaultColorName;
        }
        String dimension = (String) getCellContent(cellContents, "Size");
        if (UtilValidate.isEmpty(dimension) || UtilValidate.isEmpty(dimension.trim())) {
            dimension = defaultDimensionName;
        }
        Map<String, Object> features = updateColorAndDimension(productId, ownerPartyId, color, dimension);
        if (ServiceUtil.isError(features)) {
            if (features.containsKey("index") && String.valueOf(features.get("index")).contains("0")) {
                int cell = headerColNames.indexOf("Color");
                XSSFCell colorCell = row.getCell(cell);
                errorMessages.put(new CellReference(colorCell), UtilProperties.getMessage(resource, "PricatColorError", locale));
            }
            if (features.containsKey("index") && String.valueOf(features.get("index")).contains("1")) {
                int cell = headerColNames.indexOf("Size");
                XSSFCell colorCell = row.getCell(cell);
                errorMessages.put(new CellReference(colorCell), UtilProperties.getMessage(resource, "PricatDimensionError", locale));
            }
            return false;
        }
        String colorId = (String) features.get("colorId");
        String dimensionId = (String) features.get("dimensionId");

        // 6. update skuIds by productId
        String barcode = (String) getCellContent(cellContents, "Barcode");
        BigDecimal inventory = (BigDecimal) getCellContent(cellContents, "Stock Qty");
        BigDecimal averageCost = (BigDecimal) getCellContent(cellContents, "Average Cost");
        String skuId = updateSku(row, productId, ownerPartyId, facilityId, barcode, inventory, colorId, color, dimensionId, dimension, listPrice, averageCost);
        if (UtilValidate.isEmpty(skuId)) {
            return false;
        }

        // 7. store prices
        BigDecimal memberPrice = (BigDecimal) getCellContent(cellContents, "Member Price");
        Map<String, Object> results = updateSkuPrice(skuId, ownerPartyId, memberPrice);
        if (ServiceUtil.isError(results)) {
            return false;
        }

        return true;
    }

    public String updateSku(XSSFRow row, String productId, String ownerPartyId, String facilityId, String barcode, BigDecimal inventory,
            String colorId, String color, String dimensionId, String dimension, BigDecimal listPrice, BigDecimal averageCost) {
        return "sampleSkuId";
    }

    public String getProductId(XSSFRow row, String brandId, String modelName, String productName, String productCategoryId, String ownerPartyId, BigDecimal listPrice) {
        return "sampleProductId";
    }

    public Object getCellContent(List<Object> cellContents, String colName) {
        if (UtilValidate.isNotEmpty(headerColNames) && headerColNames.contains(colName)) {
            return cellContents.get(headerColNames.indexOf(colName));
        }
        return null;
    }

    public String getProductCategoryId(List<Object> cellContents, String ownerPartyId) {
        return "sampleProductCategoryId";
    }

    public boolean isFacilityOk(XSSFRow row, String facilityName, String facilityId) {
        if (!facilities.containsKey(facilityId)) {
            if (UtilValidate.isEmpty(facilityId) && facilities.keySet().size() == 1) {
                if (UtilValidate.isEmpty(facilityName)) {
                    return true;
                } else {
                    String theFacilityId = (String) facilities.keySet().toArray()[0];
                    String name = facilities.get(theFacilityId)[0];
                    if (!name.equals(facilityName)) {
                        String errorMessage = UtilProperties.getMessage(resource, "FacilityNameNotMatchId", new Object[]{theFacilityId, name, facilityName}, locale);
                        report.println();
                        report.print(errorMessage, InterfaceReport.FORMAT_ERROR);
                        XSSFCell cell = row.getCell(0);
                        errorMessages.put(new CellReference(cell), errorMessage);
                        return false;
                    }
                }
            } else {
                String errorMessage = UtilProperties.getMessage(resource, "FacilityNotBelongToYou", new Object[]{facilityName, facilityId}, locale);
                report.println();
                report.print(errorMessage, InterfaceReport.FORMAT_ERROR);
                XSSFCell cell = row.getCell(1);
                errorMessages.put(new CellReference(cell), errorMessage);
                return false;
            }
        } else {
            String name = facilities.get(facilityId)[0];
            if (!name.equals(facilityName)) {
                String errorMessage = UtilProperties.getMessage(resource, "FacilityNameNotMatchId", new Object[]{facilityId, name, facilityName}, locale);
                report.println();
                report.print(errorMessage, InterfaceReport.FORMAT_ERROR);
                XSSFCell cell = row.getCell(0);
                errorMessages.put(new CellReference(cell), errorMessage);
                return false;
            }
        }
        return true;
    }

    public boolean isTableHeaderMatched(XSSFSheet sheet) {
        List<Object[]> columnNames = ColNamesList.get(pricatFileVersion);
        short cols = sheet.getRow(headerRowNo).getLastCellNum();
        report.print(UtilProperties.getMessage(resource, "StartCheckHeaderColNum", new Object[] {pricatFileVersion}, locale), InterfaceReport.FORMAT_NOTE);
        if (cols != columnNames.size()) {
            report.print(UtilProperties.getMessage(resource, "HeaderColNumNotMatch", new Object[] {String.valueOf(cols), String.valueOf(columnNames.size())}, locale), InterfaceReport.FORMAT_WARNING);
            if (cols < columnNames.size()) {
                report.println(UtilProperties.getMessage(resource, "HeaderColNumShortThanRequired", new Object[] {String.valueOf(columnNames.size())}, locale), InterfaceReport.FORMAT_ERROR);
                return false;
            } else {
                report.println(UtilProperties.getMessage(resource, "UseHeaderColNum", new Object[] {String.valueOf(columnNames.size())}, locale), InterfaceReport.FORMAT_WARNING);
                cols = (short) columnNames.size();
            }
        } else {
            report.println(UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        }

        report.print(UtilProperties.getMessage(resource, "StartCheckHeaderColLabel", new Object[] {pricatFileVersion}, locale), InterfaceReport.FORMAT_NOTE);
        boolean foundLabelNotMatch = false;
        for (int i = 0; i < cols; i++) {
            String coltext = sheet.getRow(headerRowNo).getCell(i).getStringCellValue().trim();
            headerColNames.add(coltext);
            Object[] versionColumn = columnNames.get(i);
            if (!coltext.equals(versionColumn[0])) {
                report.println(UtilProperties.getMessage(resource, "HeaderColLabelNotMatch", new Object[] {String.valueOf(headerRowNo + 1), String.valueOf(i + 1), coltext, versionColumn[0]}, locale), InterfaceReport.FORMAT_ERROR);
                foundLabelNotMatch = true;
            } else {
                report.print(" " + coltext, InterfaceReport.FORMAT_NOTE);
                if (i < cols - 1) {
                    report.print(",", InterfaceReport.FORMAT_NOTE);
                }
            }
        }
        if (foundLabelNotMatch) {
            report.println();
            return false;
        }
        report.println(" ... " + UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        return true;
    }

    public boolean isVersionSupported(XSSFSheet sheet) {
        report.print(UtilProperties.getMessage(resource, "StartCheckPricatVersion", locale), InterfaceReport.FORMAT_NOTE);
        pricatFileVersion = sheet.getRow(2).getCell(0).getStringCellValue().trim();
        if (ColNamesList.containsKey(pricatFileVersion)) {
            report.print(" " + pricatFileVersion + " ... ", InterfaceReport.FORMAT_NOTE);
            report.println(UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        } else {
            report.println(UtilProperties.getMessage(resource, "error", locale), InterfaceReport.FORMAT_ERROR);
            report.println(UtilProperties.getMessage(resource, "PricatVersionNotSupport", new Object[] {pricatFileVersion}, locale), InterfaceReport.FORMAT_ERROR);
            return false;
        }
        return true;
    }

    public boolean containsDataRows(XSSFSheet sheet) {
        int rows = sheet.getPhysicalNumberOfRows();
        if (rows > headerRowNo + 1) {
            report.println(UtilProperties.getMessage(resource, "PricatTableRows", new Object[] {String.valueOf(headerRowNo + 1), String.valueOf(rows - headerRowNo - 1), sheet.getSheetName()}, locale), InterfaceReport.FORMAT_NOTE);
        } else {
            report.println(UtilProperties.getMessage(resource, "PricatNoDataRows", new Object[] {sheet.getSheetName()}, locale), InterfaceReport.FORMAT_ERROR);
            return false;
        }
        return true;
    }

    /**
     * The Object[] have 4 elements, they are:
     * 1. Header Label Name.
     * 2. Cell data type to return.
     * 3. Boolean value to indicate whether the column is required.
     * 4. Boolean value to indicate whether the column is a price when cell data type is BigDecimal, this element is optional.
     *
     * @param version
     * @return List of Object[]
     */
    private static List<Object[]> genExcelHeaderNames(String version){
        switch (version) {
            case "V1.1":
            default:
                return genExcelHeaderNamesV1_1();
        }
    }

    /**
     * Get V1.1 pricat excel header names and attributes.
     *
     * @return list of Object[]
     */
    private static List<Object[]> genExcelHeaderNamesV1_1() {
        List<Object[]> listHeaderName = new ArrayList<Object[]>();
        listHeaderName.add(new Object[] {"Facility Name",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"FacilityId",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"Category L1",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.FALSE});
        listHeaderName.add(new Object[] {"Category L2",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.FALSE});
        listHeaderName.add(new Object[] {"Category L3",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.FALSE});
        listHeaderName.add(new Object[] {"Category L4",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.FALSE});
        listHeaderName.add(new Object[] {"Brand",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"Style No",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"Product Name",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"Color",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.FALSE});
        listHeaderName.add(new Object[] {"Size",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.FALSE});
        listHeaderName.add(new Object[] {"Barcode",
                                         XSSFCell.CELL_TYPE_STRING,
                                         Boolean.FALSE});
        listHeaderName.add(new Object[] {"Stock Qty",
                                         XSSFCell.CELL_TYPE_NUMERIC,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"Average Cost",
                                         XSSFCell.CELL_TYPE_NUMERIC,
                                         Boolean.TRUE,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"List Price",
                                         XSSFCell.CELL_TYPE_NUMERIC,
                                         Boolean.TRUE,
                                         Boolean.TRUE});
        listHeaderName.add(new Object[] {"Member Price",
                                            XSSFCell.CELL_TYPE_NUMERIC,
                                            Boolean.FALSE,
                                            Boolean.TRUE});
        return listHeaderName;
    }

    @Override
    public void parsePricatExcel() {
        parsePricatExcel(true);
    }

    /**
     * Get data by version definition.
     *
     * @param row
     * @param colNames
     * @param size
     * @return
     */
    public List<Object> getCellContents(XSSFRow row, List<Object[]> colNames, int size) {
        List<Object> results = new ArrayList<Object>();
        boolean foundError = false;
        if (isEmptyRow(row, size, true)) {
            return null;
        }

        // check and get data
        for (int i = 0; i < size; i++) {
            XSSFCell cell = null;
            if (row.getPhysicalNumberOfCells() > i) {
                cell = row.getCell(i);
            }
            if (cell == null) {
                if (((Boolean) colNames.get(i)[2]).booleanValue() && (facilities.keySet().size() > 1 || (facilities.keySet().size() == 1 && i >= 2))) {
                    report.print(UtilProperties.getMessage(resource, "ErrorColCannotEmpty", new Object[] {colNames.get(i)[0]}, locale), InterfaceReport.FORMAT_WARNING);
                    cell = row.createCell(i);
                    errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource, "ErrorColCannotEmpty", new Object[] {colNames.get(i)[0]}, locale));
                    foundError = true;
                    results.add(null);
                    continue;
                } else {
                    cell = row.createCell(i);
                }
            }
            int cellType = cell.getCellType();
            String cellValue = formatter.formatCellValue(cell);
            if (UtilValidate.isNotEmpty(cellValue) && UtilValidate.isNotEmpty(cellValue.trim())) {
                if (cellType == XSSFCell.CELL_TYPE_FORMULA) {
                    try {
                        cellValue = BigDecimal.valueOf(cell.getNumericCellValue()).setScale(FinAccountHelper.decimals, FinAccountHelper.rounding).toString();
                    } catch (IllegalStateException e) {
                        try {
                            cellValue = cell.getStringCellValue();
                        } catch (IllegalStateException e1) {
                            // do nothing
                        }
                    }
                    report.print(((i == 0)?"":", ") + cellValue, InterfaceReport.FORMAT_NOTE);
                } else {
                    report.print(((i == 0)?"":", ") + cellValue, InterfaceReport.FORMAT_NOTE);
                }
            } else {
                report.print(((i == 0)?"":","), InterfaceReport.FORMAT_NOTE);
            }
            if (((Boolean) colNames.get(i)[2]).booleanValue() && UtilValidate.isEmpty(cellValue) && (facilities.keySet().size() > 1 || (facilities.keySet().size() == 1 && i >= 2))) {
                report.print(UtilProperties.getMessage(resource, "ErrorColCannotEmpty", new Object[] {colNames.get(i)[0]}, locale), InterfaceReport.FORMAT_WARNING);
                errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource, "ErrorColCannotEmpty", new Object[] {colNames.get(i)[0]}, locale));
                foundError = true;
                results.add(null);
                continue;
            }
            if (((Boolean) colNames.get(i)[2]).booleanValue() && cellType != (int) colNames.get(i)[1]) {
                // String warningMessage = "";
                if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_STRING) {
                    if (UtilValidate.isNotEmpty(cellValue) && UtilValidate.isNotEmpty(cellValue.trim())) {
                        results.add(cellValue);
                    } else {
                        results.add(null);
                    }
                } else if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_NUMERIC) {
                    if (cell.getCellType() != XSSFCell.CELL_TYPE_STRING) {
                        cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                    }
                    try {
                        results.add(BigDecimal.valueOf(Double.parseDouble(cell.getStringCellValue())).setScale(FinAccountHelper.decimals, FinAccountHelper.rounding));
                    } catch (NumberFormatException e) {
                        results.add(null);
                        errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                    }
                }
            } else {
                if (UtilValidate.isEmpty(cellValue) || UtilValidate.isEmpty(cellValue.trim())) {
                    results.add(null);
                    continue;
                }
                if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_STRING) {
                    if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                        cellValue = cell.getStringCellValue().trim();
                        results.add(cellValue);
                    } else {
                        results.add(cellValue.trim());
                    }
                } else if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_NUMERIC) {
                    if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                        try {
                            results.add(BigDecimal.valueOf(Double.valueOf(cell.getStringCellValue())));
                        } catch (NumberFormatException e) {
                            results.add(null);
                            errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                        }
                    } else if (cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {
                        try {
                            results.add(BigDecimal.valueOf(cell.getNumericCellValue()).setScale(FinAccountHelper.decimals, FinAccountHelper.rounding));
                        } catch (NumberFormatException e) {
                            results.add(null);
                            errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                        }
                    } else {
                        try {
                            results.add(BigDecimal.valueOf(Double.valueOf(cellValue)).setScale(FinAccountHelper.decimals, FinAccountHelper.rounding));
                        } catch (NumberFormatException e) {
                            results.add(null);
                            errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                        }
                    }
                }
            }
        }
        if (foundError) {
            return null;
        }
        return results;
    }

    protected int getHeaderRowNo() {
        return headerRowNo;
    }
}


text:
type HotReloadListener = () => void;

const hotReloadListeners: Set<HotReloadListener> = new Set();
export function onIntlHotReload(callback: HotReloadListener) {
  hotReloadListeners.add(callback);
}

export function offIntlHotReload(callback: HotReloadListener) {
  hotReloadListeners.delete(callback);
}

export function triggerI18nHotReload() {
  hotReloadListeners.forEach(callback => callback());
}

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0"?>
<concrete5-cif version="1.0">
	<DataType dtName="International Cats" dtHandle="international_cats">
		<Data/>
		<Data/>
		<Data/>
	</DataType>
</concrete5-cif>


text:
<?php

namespace PharmaIntelligence\GstandaardBundle\Model;

use PharmaIntelligence\GstandaardBundle\Model\om\BaseGsBewakingenTeControlerenIndicatiesPeer;

class GsBewakingenTeControlerenIndicatiesPeer extends BaseGsBewakingenTeControlerenIndicatiesPeer
{
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--<!DOCTYPE configuration>-->
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
    <!--应用名称-->
    <property name="APP_NAME" value="goodskill-mongo"/>
    <!--日志文件保存路径-->
    <property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/>
<!--    <contextName>${APP_NAME}</contextName>-->
    <!--每天记录日志到文件appender-->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>
    <!--输出到logstash的appender-->

    <springProfile name="docker">
        <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
            <!--可以访问的logstash日志收集端口-->
            <destination>logstash:4560</destination>
            <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/>
        </appender>
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
            <appender-ref ref="LOGSTASH"/>
        </root>
    </springProfile>

    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </root>
    </springProfile>
</configuration>


text:
package pp.block2.cc.ll;

import java.util.*;

import jdk.nashorn.internal.ir.Terminal;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Token;

import org.antlr.v4.runtime.misc.ParseCancellationException;
import pp.block2.cc.*;

/** Generic table-driven LL(1)-parser. */
public class GenericLLParser implements Parser {
	/** The grammar underlying this parser instance. */
	private final Grammar g;
	/** The LL-calculator for the grammar. */
	private final LLCalc calc;
	/** Map from non-terminals to maps of rules indexed by terminal. */
	private Map<NonTerm, Map<Term, Rule>> ll1Table;
	/** Current index in the token list. */
	private int index;
	/** Token list of the currently parsed input. */
	private List<? extends Token> tokens;
    /** Symbolfactory for extracting a term from a token */
    private SymbolFactory fact;

	public GenericLLParser(Grammar g) {
		this.g = g;
		this.calc = new MyLLCalc(g); // here use your own class
	}

	@Override
	public AST parse(Lexer lexer) throws ParseException {
		this.tokens = lexer.getAllTokens();
		this.index = 0;
        this.fact = new SymbolFactory(lexer.getClass());
		return parse(this.g.getStart());
	}

	/** Parses the start of the token stream according to a given
	 * symbol. If it is a terminal, that should be the first token;
	 * otherwise, it is a non-terminal that should be expanded
	 * according to the next token in the token stream, using the
	 * FIRST+-lookup table and recursively calling {@link #parse(Rule)}
	 * @param symb the symbol according to which the token stream
	 * should be parsed
	 * @return the sub-AST resulting from the parsing of symb;
	 * or null if the symbol expands to the empty string
	 * @throws ParseException if the symbol cannot be parsed
	 * because the token stream does not contain the expected symbols
	 */
	private AST parse(Symbol symb) throws ParseException {
        AST res = null;
        if (symb instanceof Term) {
            if (index >= tokens.size()) {
                throw new ParseException("Reached eof too soon");
            }
            if(symb != Symbol.EMPTY) {
                try {
                    res = new AST((Term) symb, tokens.get(index));
                } catch (AssertionError e) {
                    throw new ParseException("Token type not equal to symbol type!");
                }
                index++;
            }
        } else {
            Rule r = lookup((NonTerm) symb);
            res = parse(r);
        }
        return res;
	}

	/** Parses the start of the token stream according to a given
	 * rule, recursively calling {@link #parse(Symbol)} to process
	 * the RHS.
	 * @return the sub-AST resulting from the parsing of the rule.
	 * The top node is the node for the LHS of the rule, its direct
	 * children correspond to the symbols of the rule's RHS.
	 * @throws ParseException if the symbol cannot be parsed
	 * because the token stream does not contain the expected symbols
	 */
	private AST parse(Rule r) throws ParseException {
        AST res = new AST(r.getLHS());
        int i = 0;
        while (i < r.getRHS().size()) {
            Symbol symbol = r.getRHS().get(i);
            res.addChild(parse(symbol));
            i++;
        }
        return res;
	}

	/** Uses the lookup table to look up the rule to which
	 * a given nonterminal should be expanded.
	 * The next rule is determined by the next token, using the
	 * FIRST+-set of the nonterminal.
	 * @throws ParseException if the lookup table does not
	 * contain a rule for the nonterminal in combination with
	 * the first token in the token stream.
	 */
	private Rule lookup(NonTerm nt) throws ParseException {
		Rule result;
		if (atEnd()) {
			result = getLL1Table().get(nt).get(Term.EOF);
			if (result == null) {
				throw new ParseException("Reading beyond end of input");
			}
		} else {
			Token nextToken = peek();
			Term term = this.g.getTerminal(nextToken.getType());
			result = getLL1Table().get(nt).get(term);
			if (result == null) {
				throw new ParseException(String.format(
						"Line %d:%d - no rule for '%s' on token '%s'",
						nextToken.getLine(), nextToken.getCharPositionInLine(),
						nt.getName(), nextToken));
			}
		}
		return result;
	}

	/** Tests whether the end of input has been reached. */
	private boolean atEnd() {
		return this.index >= this.tokens.size();
	}

	/** Returns the next token, without moving the token index. */
	private Token peek() throws ParseException {
		if (this.index >= this.tokens.size()) {
			throw new ParseException("Reading beyond end of input");
		}
		return this.tokens.get(this.index);
	}

	/** Returns the next token and moves up the token index. */
	private Token next() throws ParseException {
		Token result = peek();
		this.index++;
		return result;
	}

	/** Lazily builds and then returns the lookup table. */
	private Map<NonTerm, Map<Term, Rule>> getLL1Table() {
		if (this.ll1Table == null) {
			this.ll1Table = calcLL1Table();
		}
		return this.ll1Table;
	}

	/** Constructs the {@link #ll1Table}. */
	private Map<NonTerm, Map<Term, Rule>> calcLL1Table() {
        Map<NonTerm, Map<Term, Rule>> res = new HashMap<>();
        for (NonTerm A : g.getNonterminals()) {
            Map<Term, Rule> innermap = new HashMap<>();
            for (Term w : g.getTerminals()) {
                innermap.put(w, null);
            }
            res.put(A, innermap);
            for (Rule r : g.getRules()) {
                if (r.getLHS().equals(A)) {
                    Set<Term> firstpset = calc.getFirstp().get(r);
                    for (Term w : firstpset) {
                        res.get(A).put(w, r);
                    }
                    if (firstpset.contains(Symbol.EOF)) {
                        res.get(A).put(Symbol.EOF, r);
                    }
                }
            }
        }
        return res;
	}
}


text:
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cstdarg>

#include <string>
#include <iostream>
#include <unordered_map>
#include <cinttypes>
#include <string_view>
#include <array>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "ts/ts.h"
#include "ts/remap.h"
#include "background_fetch.h"
using OutstandingRequests = std::unordered_map<std::string, bool>;

///////////////////////////////////////////////////////////////////////////
// Set a header to a specific value. This will avoid going to through a
// remove / add sequence in case of an existing header.
// but clean.
static bool
set_header(TSMBuffer bufp, TSMLoc hdr_loc, const char *header, int len, const char *val, int val_len)
{
  if (!bufp || !hdr_loc || !header || len <= 0 || !val || val_len <= 0) {
    return false;
  }

  bool ret         = false;
  TSMLoc field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, header, len);

  if (!field_loc) {
    // No existing header, so create one
    if (TS_SUCCESS == TSMimeHdrFieldCreateNamed(bufp, hdr_loc, header, len, &field_loc)) {
      if (TS_SUCCESS == TSMimeHdrFieldValueStringSet(bufp, hdr_loc, field_loc, -1, val, val_len)) {
        TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
        ret = true;
      }
      TSHandleMLocRelease(bufp, hdr_loc, field_loc);
    }
  } else {
    TSMLoc tmp = nullptr;
    bool first = true;

    while (field_loc) {
      tmp = TSMimeHdrFieldNextDup(bufp, hdr_loc, field_loc);
      if (first) {
        first = false;
        if (TS_SUCCESS == TSMimeHdrFieldValueStringSet(bufp, hdr_loc, field_loc, -1, val, val_len)) {
          ret = true;
        }
      } else {
        TSMimeHdrFieldDestroy(bufp, hdr_loc, field_loc);
      }
      TSHandleMLocRelease(bufp, hdr_loc, field_loc);
      field_loc = tmp;
    }
  }

  return ret;
}

///////////////////////////////////////////////////////////////////////////
// Dump a header on stderr, useful together with TSDebug().
static void
dump_headers(TSMBuffer bufp, TSMLoc hdr_loc)
{
  TSIOBuffer output_buffer;
  TSIOBufferReader reader;
  TSIOBufferBlock block;
  int64_t block_avail;

  output_buffer = TSIOBufferCreate();
  reader        = TSIOBufferReaderAlloc(output_buffer);

  /* This will print  just MIMEFields and not the http request line */
  TSMimeHdrPrint(bufp, hdr_loc, output_buffer);

  /* We need to loop over all the buffer blocks, there can be more than 1 */
  block = TSIOBufferReaderStart(reader);
  do {
    const char *block_start = TSIOBufferBlockReadStart(block, reader, &block_avail);
    if (block_avail > 0) {
      TSDebug(PLUGIN_NAME, "Headers are:\n%.*s", static_cast<int>(block_avail), block_start);
    }
    TSIOBufferReaderConsume(reader, block_avail);
    block = TSIOBufferReaderStart(reader);
  } while (block && block_avail != 0);

  /* Free up the TSIOBuffer that we used to print out the header */
  TSIOBufferReaderFree(reader);
  TSIOBufferDestroy(output_buffer);
}

bool
BgFetchData::initialize(TSMBuffer request, TSMLoc req_hdr, TSHttpTxn txnp)
{
  struct sockaddr const *ip = TSHttpTxnClientAddrGet(txnp);
  bool ret                  = false;

  TSAssert(TS_NULL_MLOC == hdr_loc);
  TSAssert(TS_NULL_MLOC == url_loc);

  if (ip) {
    if (ip->sa_family == AF_INET) {
      memcpy(&client_ip, ip, sizeof(sockaddr_in));
    } else if (ip->sa_family == AF_INET6) {
      memcpy(&client_ip, ip, sizeof(sockaddr_in6));
    } else {
      TSError("[%s] Unknown address family %d", PLUGIN_NAME, ip->sa_family);
    }
  } else {
    TSError("[%s] Failed to get client host info", PLUGIN_NAME);
    return false;
  }

  hdr_loc = TSHttpHdrCreate(mbuf);
  if (TS_SUCCESS == TSHttpHdrCopy(mbuf, hdr_loc, request, req_hdr)) {
    TSMLoc p_url;

    // Now copy the pristine request URL into our MBuf
    if (TS_SUCCESS == TSHttpTxnPristineUrlGet(txnp, &request, &p_url)) {
      if (TS_SUCCESS == TSUrlClone(mbuf, request, p_url, &url_loc)) {
        TSMLoc c_url = TS_NULL_MLOC;
        int len;
        char *url = nullptr;

        // Get the cache key URL (for now), since this has better lookup behavior when using
        // e.g. the cachekey plugin.
        if (TS_SUCCESS == TSUrlCreate(request, &c_url)) {
          if (TS_SUCCESS == TSHttpTxnCacheLookupUrlGet(txnp, request, c_url)) {
            url = TSUrlStringGet(request, c_url, &len);
            TSHandleMLocRelease(request, TS_NULL_MLOC, c_url);
            TSDebug(PLUGIN_NAME, "Cache URL is %.*s", len, url);
          }
        }

        if (url) {
          _url.assign(url, len); // Save away the cache URL for later use when acquiring lock
          TSfree(static_cast<void *>(url));

          if (TS_SUCCESS == TSHttpHdrUrlSet(mbuf, hdr_loc, url_loc)) {
            // Make sure we have the correct Host: header for this request.
            const char *hostp = TSUrlHostGet(mbuf, url_loc, &len);

            if (set_header(mbuf, hdr_loc, TS_MIME_FIELD_HOST, TS_MIME_LEN_HOST, hostp, len)) {
              TSDebug(PLUGIN_NAME, "Set header Host: %.*s", len, hostp);
            }
            ret = true;
          }
        }
      }
      TSHandleMLocRelease(request, TS_NULL_MLOC, p_url);
    }
  }

  return ret;
}

static int cont_bg_fetch(TSCont contp, TSEvent event, void *edata);

// Create, setup and schedule the background fetch continuation.
void
BgFetchData::schedule()
{
  TSAssert(nullptr == _cont);

  // Setup the continuation
  _cont = TSContCreate(cont_bg_fetch, TSMutexCreate());
  TSContDataSet(_cont, static_cast<void *>(this));

  // Initialize the VIO stuff (for the fetch)
  req_io_buf         = TSIOBufferCreate();
  req_io_buf_reader  = TSIOBufferReaderAlloc(req_io_buf);
  resp_io_buf        = TSIOBufferCreate();
  resp_io_buf_reader = TSIOBufferReaderAlloc(resp_io_buf);

  // Schedule
  TSContScheduleOnPool(_cont, 0, TS_THREAD_POOL_NET);
}

//////////////////////////////////////////////////////////////////////////////
// Continuation to perform a background fill of a URL. This is pretty
// expensive (memory allocations etc.), we could eliminate maybe the
// std::string, but I think it's fine for now.
static int
cont_bg_fetch(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
{
  BgFetchData *data = static_cast<BgFetchData *>(TSContDataGet(contp));
  int64_t avail;

  switch (event) {
  case TS_EVENT_IMMEDIATE:
  case TS_EVENT_TIMEOUT:
    // Debug info for this particular bg fetch (put all debug in here please)
    if (TSIsDebugTagSet(PLUGIN_NAME)) {
      char buf[INET6_ADDRSTRLEN];
      const sockaddr *sockaddress = reinterpret_cast<const sockaddr *>(&data->client_ip);

      switch (sockaddress->sa_family) {
      case AF_INET:
        inet_ntop(AF_INET, &(((struct sockaddr_in *)sockaddress)->sin_addr), buf, INET_ADDRSTRLEN);
        TSDebug(PLUGIN_NAME, "Client IPv4 = %s", buf);
        break;
      case AF_INET6:
        inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sockaddress)->sin6_addr), buf, INET6_ADDRSTRLEN);
        TSDebug(PLUGIN_NAME, "Client IPv6 = %s", buf);
        break;
      default:
        TSError("[%s] Unknown address family %d", PLUGIN_NAME, sockaddress->sa_family);
        break;
      }
      TSDebug(PLUGIN_NAME, "Starting background fetch, replaying:");
      dump_headers(data->mbuf, data->hdr_loc);
    }

    // Setup the NetVC for background fetch
    TSAssert(nullptr == data->vc);
    if ((data->vc = TSHttpConnectWithPluginId(reinterpret_cast<sockaddr *>(&data->client_ip), PLUGIN_NAME, 0)) != nullptr) {
      TSHttpHdrPrint(data->mbuf, data->hdr_loc, data->req_io_buf);
      // We never send a body with the request. ToDo: Do we ever need to support that ?
      TSIOBufferWrite(data->req_io_buf, "\r\n", 2);

      data->r_vio = TSVConnRead(data->vc, contp, data->resp_io_buf, INT64_MAX);
      data->w_vio = TSVConnWrite(data->vc, contp, data->req_io_buf_reader, TSIOBufferReaderAvail(data->req_io_buf_reader));
    } else {
      delete data;
      TSError("[%s] Failed to connect to internal process, major malfunction", PLUGIN_NAME);
    }
    break;

  case TS_EVENT_VCONN_WRITE_COMPLETE:
    // TSVConnShutdown(data->vc, 0, 1);
    // TSVIOReenable(data->w_vio);
    TSDebug(PLUGIN_NAME, "Write Complete");
    break;

  case TS_EVENT_VCONN_READ_READY:
    avail = TSIOBufferReaderAvail(data->resp_io_buf_reader);
    data->addBytes(avail);
    TSIOBufferReaderConsume(data->resp_io_buf_reader, avail);
    TSVIONDoneSet(data->r_vio, TSVIONDoneGet(data->r_vio) + avail);
    TSVIOReenable(data->r_vio);
    break;

  case TS_EVENT_VCONN_READ_COMPLETE:
  case TS_EVENT_VCONN_EOS:
  case TS_EVENT_VCONN_INACTIVITY_TIMEOUT:
  case TS_EVENT_ERROR:
    if (event == TS_EVENT_VCONN_INACTIVITY_TIMEOUT) {
      TSDebug(PLUGIN_NAME, "Encountered Inactivity Timeout");
      TSVConnAbort(data->vc, TS_VC_CLOSE_ABORT);
    } else {
      TSVConnClose(data->vc);
    }

    TSDebug(PLUGIN_NAME, "Closing down background transaction, event= %s(%d)", TSHttpEventNameLookup(event), event);
    avail = TSIOBufferReaderAvail(data->resp_io_buf_reader);
    data->addBytes(avail);
    TSIOBufferReaderConsume(data->resp_io_buf_reader, avail);
    TSVIONDoneSet(data->r_vio, TSVIONDoneGet(data->r_vio) + avail);

    // Close, release and cleanup
    data->vc = nullptr;
    delete data;
    break;

  default:
    TSDebug(PLUGIN_NAME, "Unhandled event: %s (%d)", TSHttpEventNameLookup(event), event);
    break;
  }

  return 0;
}


text:
 /*
 * $Id: XMLValidator.hpp 568078 2007-08-21 11:43:25Z amassari $
 */

#if !defined(XMLVALIDATOR_HPP)
#define XMLVALIDATOR_HPP

#include <xercesc/framework/XMLAttr.hpp>
#include <xercesc/framework/XMLValidityCodes.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class ReaderMgr;
class XMLBufferMgr;
class XMLElementDecl;
class XMLScanner;
class Grammar;

/**
 *  This abstract class provides the interface for all validators. This is
 *  the simple amount of API that all validators must honor, in order for
 *  the scanner to use them to do validation. All validators will actually
 *  contain much more functionality than is accessible via this common API,
 *  but that functionality requires that you know what type of validator you
 *  are dealing with.
 *
 *  Basically, at this level, the primary concern is to be able to query
 *  core information about elements and attributes. Adding decls to the
 *  validator requires that you go through the derived interface because they
 *  all have their own decl types. At this level, we can return information
 *  via the base decl classes, from which each validator derives its own
 *  decl classes.
 */
class XMLPARSER_EXPORT XMLValidator : public XMemory
{
public:
    // -----------------------------------------------------------------------
    //  Constructors are hidden, just the virtual destructor is exposed
    // -----------------------------------------------------------------------

    /** @name Destructor */
    //@{

    /**
     *  The derived class should clean up its allocated data, then this class
     *  will do the same for data allocated at this level.
     */
    virtual ~XMLValidator()
    {
    }
    //@}

    // -----------------------------------------------------------------------
    //  The virtual validator interface
    // -----------------------------------------------------------------------

    /** @name Virtual validator interface */
    //@{

    /**
      * The derived class should look up its declaration of the passed element
      * from its element pool. It should then use the content model description
      * contained in that element declaration to validate that the passed list
      * of child elements are valid for that content model. The count can be
      * zero, indicating no child elements.
      *
      * Note that whitespace and text content are not validated here. Those are
      * handled by the scanner. So only element ids are provided here.
      *
      * @param  elemDecl    The element whose content is to be checked.
      *
      * @param  children    An array of element QName which represent the elements
      *                     found within the parent element, i.e. the content
      *                     to be validated.
      *
      * @param  childCount  The number of elements in the childIds array. It can
      *                     be zero if the element had none.
      */
    virtual int checkContent
    (
        XMLElementDecl* const   elemDecl
        , QName** const         children
        , const unsigned int    childCount
    ) = 0;

    /**
      * The derived class should fault in the passed XMLAttr value. It should
      * use the passeed attribute definition (which is passed via the base
      * type so it must often be downcast to the appropriate type for the
      * derived validator class), to fill in the passed attribute. This is done
      * as a performance enhancement since the derived class has more direct
      * access to the information.
      */
    virtual void faultInAttr
    (
                XMLAttr&    toFill
        , const XMLAttDef&  attDef
    )   const = 0;

    /**
      * This method is called by the scanner after a Grammar is scanned.
      */
    virtual void preContentValidation(bool reuseGrammar,
                                      bool validateDefAttr = false) = 0;

    /**
      * This method is called by the scanner after the parse has completed. It
      * gives the validator a chance to check certain things that can only be
      * checked after the whole document has been parsed, such as referential
      * integrity of ID/IDREF pairs and so forth. The validator should just
      * issue errors for any problems it finds.
      */
    virtual void postParseValidation() = 0;

    /**
      * This method is called by the scanner before a new document is about
      * to start. It gives the validator a change to reset itself in preperation
      * for another validation pass.
      */
    virtual void reset() = 0;

    /**
      * The derived class should return a boolean that indicates whether it
      * requires namespace processing or not. Some do and some allow it to be
      * optional. This flag is used to control whether the client code's
      * requests to disable namespace processing can be honored or not.
      */
    virtual bool requiresNamespaces() const = 0;

    /**
      * The derived class should apply any rules to the passed attribute value
      * that are above and beyond those defined by XML 1.0. The scanner itself
      * will impose XML 1.0 rules, based on the type of the attribute. This
      * will generally be used to check things such as range checks and other
      * datatype related validation.
      *
      * If the value breaks any rules as defined by the derived class, it
      * should just issue errors as usual.
      */
    virtual void validateAttrValue
    (
        const   XMLAttDef*                  attDef
        , const XMLCh* const                attrValue
        , bool                              preValidation = false
        , const XMLElementDecl*             elemDecl = 0
    ) = 0;

    /**
      * The derived class should apply any rules to the passed element decl
      * that are above and beyond those defined by XML 1.0.
      *
      * If the value breaks any rules as defined by the derived class, it
      * should just issue errors as usual.
      */
    virtual void validateElement
    (
        const   XMLElementDecl*             elemDef
    ) = 0;

    /**
      * Retrieve the Grammar used
      */
    virtual Grammar* getGrammar() const =0;

    /**
      * Set the Grammar
      */
    virtual void setGrammar(Grammar* aGrammar) =0;

    //@}

    // -----------------------------------------------------------------------
    //  Virtual DTD handler interface.
    // -----------------------------------------------------------------------

    /** @name Virtual DTD handler interface */
    //@{

    /**
      * This method allows the scanner to ask the validator if it handles
      * DTDs or not.
      */
    virtual bool handlesDTD() const = 0;

    // -----------------------------------------------------------------------
    //  Virtual Schema handler interface.
    // -----------------------------------------------------------------------

    /** @name Virtual Schema handler interface */

    /**
      * This method allows the scanner to ask the validator if it handles
      * Schema or not.
      */
    virtual bool handlesSchema() const = 0;

    //@}

    // -----------------------------------------------------------------------
    //  Setter methods
    //
    //  setScannerInfo() is called by the scanner to tell the validator
    //  about the stuff it needs to have access to.
    // -----------------------------------------------------------------------

    /** @name Setter methods */
    //@{

    /**
      * @param  owningScanner   This is a pointer to the scanner to which the
      *                         validator belongs. The validator will often
      *                         need to query state data from the scanner.
      *
      * @param  readerMgr       This is a pointer to the reader manager that is
      *                         being used by the scanner.
      *
      * @param  bufMgr          This is the buffer manager of the scanner. This
      *                         is provided as a convenience so that the validator
      *                         doesn't have to create its own buffer manager
      *                         during the parse process.
      */
    void setScannerInfo
    (
        XMLScanner* const           owningScanner
        , ReaderMgr* const          readerMgr
        , XMLBufferMgr* const       bufMgr
    );

    /**
      * This method is called to set an error reporter on the validator via
      * which it will report any errors it sees during parsing or validation.
      * This is generally called by the owning scanner.
      *
      * @param  errorReporter   A pointer to the error reporter to use. This
      *                         is not adopted, just referenced so the caller
      *                         remains responsible for its cleanup, if any.
      */
    void setErrorReporter
    (
        XMLErrorReporter* const errorReporter
    );

    //@}

    // -----------------------------------------------------------------------
    //  Error emitter methods
    // -----------------------------------------------------------------------

    /** @name Error emittor methods */
    //@{

    /**
     *  This call is a convenience by which validators can emit errors. Most
     *  of the grunt work of loading the text, getting the current source
     *  location, ect... is handled here.
     *
     *  If the loaded text has replacement parameters, then text strings can be
     *  passed. These will be used to replace the tokens {0}, {1}, {2}, and {3}
     *  in the order passed. So text1 will replace {0}, text2 will replace {1},
     *  and so forth.
     *
     *  textX   Up to four replacement parameters. They can be provided
     *          as either XMLCh strings, or local code page strings which
     *          will be transcoded internally.
     *
     *  @param toEmit   The error code to emit. it must be one of the defined
     *                  validator error codes.
     *
     */
    void emitError(const XMLValid::Codes toEmit);
    void emitError
    (
        const   XMLValid::Codes toEmit
        , const XMLCh* const    text1
        , const XMLCh* const    text2 = 0
        , const XMLCh* const    text3 = 0
        , const XMLCh* const    text4 = 0
    );
    void emitError
    (
        const   XMLValid::Codes toEmit
        , const char* const     text1
        , const char* const     text2 = 0
        , const char* const     text3 = 0
        , const char* const     text4 = 0
    );
    void emitError
    (
        const   XMLValid::Codes toEmit
        , const XMLExcepts::Codes   originalErrorCode
        , const XMLCh* const        text1 = 0
        , const XMLCh* const        text2 = 0
        , const XMLCh* const        text3 = 0
        , const XMLCh* const        text4 = 0

    );

    //@}

    // -----------------------------------------------------------------------
    //  Deprecated XMLValidator interface
    // -----------------------------------------------------------------------
    /**
      *
      * DEPRECATED.
      * For those validators that contrain the possible root elements of a
      * document to only particular elements, they should use this call to
      * validate that the passed root element id is a legal root element.
      */
    bool checkRootElement
    (
        const   unsigned int
    ) { return true;};

    // -----------------------------------------------------------------------
    //  Notification that lazy data has been deleted
    // -----------------------------------------------------------------------
	static void reinitMsgMutex();

	static void reinitMsgLoader();

protected :
    // -----------------------------------------------------------------------
    //  Hidden constructors
    // -----------------------------------------------------------------------
    XMLValidator
    (
        XMLErrorReporter* const errReporter = 0
    );

    // -----------------------------------------------------------------------
    //  Protected getters
    // -----------------------------------------------------------------------
    const XMLBufferMgr* getBufMgr() const;
    XMLBufferMgr* getBufMgr();
    const ReaderMgr* getReaderMgr() const;
    ReaderMgr* getReaderMgr();
    const XMLScanner* getScanner() const;
    XMLScanner* getScanner();

private :
    // -----------------------------------------------------------------------
    //  Unimplemented Constructors and Operators
    // -----------------------------------------------------------------------
    XMLValidator(const XMLValidator&);
    XMLValidator& operator=(const XMLValidator&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fErrorReporter
    //      The error reporter we are to use, if any.
    //
    // -----------------------------------------------------------------------
    XMLBufferMgr*       fBufMgr;
    XMLErrorReporter*   fErrorReporter;
    ReaderMgr*          fReaderMgr;
    XMLScanner*         fScanner;
};

// -----------------------------------------------------------------------
//  Setter methods
// -----------------------------------------------------------------------
inline void
XMLValidator::setScannerInfo(XMLScanner* const      owningScanner
                            , ReaderMgr* const      readerMgr
                            , XMLBufferMgr* const   bufMgr)
{
    // We don't own any of these, we just reference them
    fScanner = owningScanner;
    fReaderMgr = readerMgr;
    fBufMgr = bufMgr;
}

inline void
XMLValidator::setErrorReporter(XMLErrorReporter* const errorReporter)
{
    fErrorReporter = errorReporter;
}

// ---------------------------------------------------------------------------
//  XMLValidator: Protected getter
// ---------------------------------------------------------------------------
inline const XMLBufferMgr* XMLValidator::getBufMgr() const
{
    return fBufMgr;
}

inline XMLBufferMgr* XMLValidator::getBufMgr()
{
    return fBufMgr;
}

inline const ReaderMgr* XMLValidator::getReaderMgr() const
{
    return fReaderMgr;
}

inline ReaderMgr* XMLValidator::getReaderMgr()
{
    return fReaderMgr;
}

inline const XMLScanner* XMLValidator::getScanner() const
{
    return fScanner;
}

inline XMLScanner* XMLValidator::getScanner()
{
    return fScanner;
}

XERCES_CPP_NAMESPACE_END

#endif


text:
<?php

namespace Zenstruck\CacheBundle\Url;

use Http\Client\HttpClient;
use Http\Message\MessageFactory;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

/**
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class Crawler implements \Countable
{
    private $httpClient;
    private $messageFactory;
    private $logger;
    private $urlProviders;

    /**
     * @param HttpClient      $httpClient
     * @param MessageFactory  $messageFactory
     * @param LoggerInterface $logger
     * @param UrlProvider[]   $urlProviders
     */
    public function __construct(HttpClient $httpClient, MessageFactory $messageFactory, LoggerInterface $logger = null, array $urlProviders = [])
    {
        $this->httpClient = $httpClient;
        $this->messageFactory = $messageFactory;
        $this->logger = $logger;
        $this->urlProviders = $urlProviders;
    }

    /**
     * @param UrlProvider $provider
     */
    public function addUrlProvider(UrlProvider $provider)
    {
        $this->urlProviders[] = $provider;
    }

    /**
     * {@inheritdoc}
     */
    public function count()
    {
        $count = 0;

        foreach ($this->urlProviders as $provider) {
            $count += count($provider);
        }

        return $count;
    }

    /**
     * @param callable $callback Response as first argument, calling URL as second
     */
    public function crawl(callable $callback = null)
    {
        foreach ($this->getUrls() as $url) {
            $response = $this->httpClient->sendRequest($this->messageFactory->createRequest('GET', $url));

            $this->log($response, $url);

            if ($callback) {
                $callback($response, $url);
            }
        }
    }

    /**
     * @param ResponseInterface $response
     * @param string            $url
     */
    private function log(ResponseInterface $response, $url)
    {
        if (null === $this->logger) {
            return;
        }

        $status = $response->getStatusCode();

        $this->logger->log($status == 200 ? LogLevel::DEBUG : LogLevel::NOTICE, sprintf('[%s] %s', $status, $url));
    }

    /**
     * @return array
     */
    private function getUrls()
    {
        $urls = [];

        foreach ($this->urlProviders as $provider) {
            $urls = array_merge($urls, $provider->getUrls());
        }

        return $urls;
    }
}


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta name="description" content="Gestion des tickets" />
    <meta name="keywords" content="coworkinglille, coworking, lille" />
    <title>CoworkingLille Ticket</title>
    <link rel="stylesheet" href="<?php echo base_url(); ?>css/style.css" media="screen" />

Gestion des tickets


text:
from django.apps import AppConfig

class ApisConfig(AppConfig):
    name = 'APIs'


text:
/**
 * @jest-environment jsdom
 */

import InputDriver, {
  keyFromKeyboardEvent,
} from "../../src/content/InputDriver";
import Key from "../../src/shared/settings/Key";

describe("InputDriver", () => {
  let target: HTMLElement;
  let driver: InputDriver;

  beforeEach(() => {
    target = document.createElement("div");
    document.body.appendChild(target);
    driver = new InputDriver(target);
  });

  afterEach(() => {
    target.remove();
  });

  it("register callbacks", (done) => {
    driver.onKey((key: Key): boolean => {
      expect(key.key).toEqual("a");
      expect(key.ctrl).toBeTruthy;
      expect(key.shift).toBeFalsy;
      expect(key.alt).toBeFalsy;
      expect(key.meta).toBeFalsy;
      done();
      return true;
    });

    target.dispatchEvent(
      new KeyboardEvent("keydown", {
        key: "a",
        ctrlKey: true,
        shiftKey: false,
        altKey: false,
        metaKey: false,
      })
    );
  });

  it("invoke callback once", () => {
    let a = 0,
      b = 0;
    driver.onKey((key: Key): boolean => {
      if (key.key == "a") {
        ++a;
      } else {
        key.key == "b";
        ++b;
      }
      return true;
    });

    const events = [
      new KeyboardEvent("keydown", { key: "a" }),
      new KeyboardEvent("keydown", { key: "b" }),
      new KeyboardEvent("keypress", { key: "a" }),
      new KeyboardEvent("keyup", { key: "a" }),
      new KeyboardEvent("keypress", { key: "b" }),
      new KeyboardEvent("keyup", { key: "b" }),
    ];
    for (const e of events) {
      target.dispatchEvent(e);
    }

    expect(a).toEqual(1);
    expect(b).toEqual(1);
  });

  it("propagates and stop handler chain", () => {
    let a = 0,
      b = 0,
      c = 0;
    driver.onKey((_key: Key): boolean => {
      a++;
      return false;
    });
    driver.onKey((_key: Key): boolean => {
      b++;
      return true;
    });
    driver.onKey((_key: Key): boolean => {
      c++;
      return true;
    });

    target.dispatchEvent(new KeyboardEvent("keydown", { key: "b" }));

    expect(a).toEqual(1);
    expect(b).toEqual(1);
    expect(c).toEqual(0);
  });

  it("does not invoke only meta keys", () => {
    driver.onKey((_key: Key): boolean => {
      throw new Error("unexpected reach");
      return false;
    });

    target.dispatchEvent(new KeyboardEvent("keydown", { key: "Shift" }));
    target.dispatchEvent(new KeyboardEvent("keydown", { key: "Control" }));
    target.dispatchEvent(new KeyboardEvent("keydown", { key: "Alt" }));
    target.dispatchEvent(new KeyboardEvent("keydown", { key: "OS" }));
  });

  it("ignores events from input elements", () => {
    ["input", "textarea", "select"].forEach((name) => {
      const input = window.document.createElement(name);
      const driver = new InputDriver(input);
      driver.onKey((_key: Key): boolean => {
        throw new Error("unexpected reach");
        return false;
      });
      input.dispatchEvent(new KeyboardEvent("keydown", { key: "x" }));
    });
  });

  it("ignores events from contenteditable elements", () => {
    const div = window.document.createElement("div");
    const driver = new InputDriver(div);
    driver.onKey((_key: Key): boolean => {
      throw new Error("unexpected reach");
      return false;
    });

    div.setAttribute("contenteditable", "");
    div.dispatchEvent(new KeyboardEvent("keydown", { key: "x" }));

    div.setAttribute("contenteditable", "true");
    div.dispatchEvent(new KeyboardEvent("keydown", { key: "x" }));
  });
});

describe("#keyFromKeyboardEvent", () => {
  it("returns from keyboard input Ctrl+X", () => {
    const k = keyFromKeyboardEvent(
      new KeyboardEvent("keydown", {
        key: "x",
        shiftKey: false,
        ctrlKey: true,
        altKey: false,
        metaKey: true,
      })
    );
    expect(k.key).toEqual("x");
    expect(k.shift).toBeFalsy;
    expect(k.ctrl).toBeTruthy;
    expect(k.alt).toBeFalsy;
    expect(k.meta).toBeTruthy;
  });

  it("returns from keyboard input Shift+Esc", () => {
    const k = keyFromKeyboardEvent(
      new KeyboardEvent("keydown", {
        key: "Escape",
        shiftKey: true,
        ctrlKey: false,
        altKey: false,
        metaKey: true,
      })
    );
    expect(k.key).toEqual("Esc");
    expect(k.shift).toBeTruthy;
    expect(k.ctrl).toBeFalsy;
    expect(k.alt).toBeFalsy;
    expect(k.meta).toBeTruthy;
  });

  it("returns from keyboard input Ctrl+$", () => {
    // $ required shift pressing on most keyboards
    const k = keyFromKeyboardEvent(
      new KeyboardEvent("keydown", {
        key: "$",
        shiftKey: true,
        ctrlKey: true,
        altKey: false,
        metaKey: false,
      })
    );
    expect(k.key).toEqual("$");
    expect(k.shift).toBeFalsy;
    expect(k.ctrl).toBeTruthy;
    expect(k.alt).toBeFalsy;
    expect(k.meta).toBeFalsy;
  });

  it("returns from keyboard input Crtl+Space", () => {
    const k = keyFromKeyboardEvent(
      new KeyboardEvent("keydown", {
        key: " ",
        shiftKey: false,
        ctrlKey: true,
        altKey: false,
        metaKey: false,
      })
    );
    expect(k.key).toEqual("Space");
    expect(k.shift).toBeFalsy;
    expect(k.ctrl).toBeTruthy;
    expect(k.alt).toBeFalsy;
    expect(k.meta).toBeFalsy;
  });
});


text:
from django.conf.urls import patterns, include, url
from . import views

# Uncomment the next two lines to enable the admin:

urlpatterns = patterns('',
       # user is out
       url(r'^j/login/$', views.login, name="account_login"),
       url(r'^j/register/$', views.register, name='account_signup'),
       url(r"^password/reset/$", views.password_reset, name="account_student_reset_password"),
       url(r'^confirm_email/(?P<key>\w+)/$', views.confirm_email, name="account_student_confirm_email"),
       url(r'^confirm_sms_account/(?P<key>\w+)/$', views.confirm_sms_account, name="account_student_confirm_sms"),
       url('^(?P<provider>.*)/signup/$', views.social_login, name='socialaccount_signup'),

)


text:
<?php

namespace Cac\BarBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Cac\BarBundle\Entity\Bar;
use Cac\BarBundle\Entity\Promotion;
use Cac\BarBundle\Entity\PromotionDummy;
use Cac\BarBundle\Form\Type\BarType;
use Cac\BarBundle\Form\Type\PromotionType;
use Cac\BarBundle\Form\Type\PromotionDummyType;
use Symfony\Component\HttpFoundation\JsonResponse;
use Hip\MandrillBundle\Message;
/**
 * Bar controller.
 *
 * @Route("/bars/promotion")
 */
class PromotionController extends Controller
{
	/**
     * Displays the promotion and happy-hours interface for an existing Bar entity.
     *
     * @Route("/{id}/new-part3", name="promotion_create")
     * @Method("GET")
     * @Template("CacBarBundle:Promotion:createPromo.html.twig")
     */
    public function createPromoAction($id)
    {
        $em = $this->getDoctrine()->getManager();
        $user = $this->get('security.context')->getToken()->getUser();

        $plan = $em->getRepository('CacPaymentBundle:Payment')->findOneByUser($user);
        if ($plan != null) {
            $planName = $em->getRepository('CacPaymentBundle:Payment')->findOneByUser($user)->getPlan();
        }
        else
            $planName = "shooter";

        $entity = $em->getRepository('CacBarBundle:Bar')->find($id);
        $promotions = $entity->getPromotions();
        $promotionDummy = new PromotionDummy();

        $restriction = $em->getRepository('CacBarBundle:PromotionOptionCategory')->findOneByShortcode('restriction');
        $restrictions = $em->getRepository('CacBarBundle:PromotionOption')->findByCategory($restriction);

        if (!$entity) {
            throw $this->createNotFoundException('Le bar demandé n\'existe pas.');
        }

        $editForm = $this->createEditForm($promotionDummy, $entity);

        return array(
            'promotions'        => $promotions,
            'promotionDummy'    => $promotionDummy,
            'form'              => $editForm->createView(),
            'restrictions'      => $restrictions,
            'id'                => $entity->getId(),
            'bar'               => $entity,
            'plan'              => $plan
        );
    }

    /**
    * Creates a form to edit a Bar entity.
    *
    * @param Bar $entity The entity
    *
    * @return \Symfony\Component\Form\Form The form
    */
    private function createEditForm(PromotionDummy $promotionDummy, Bar $entity)
    {
        $form = $this->createForm(new PromotionDummyType(), $promotionDummy, array(
            'action' => $this->generateUrl('promotion_update', array('id' => $entity->getId())),
            'method' => 'PUT',
        ));

        $form->add('submit',
            'submit',
            array(
                'label' => 'Valider'
            )
        );

        return $form;
    }

    /**
     * Edits an existing Bar entity.
     *
     * @Route("/{id}", name="promotion_update")
     * @Method("PUT")
     * @Template("CacBarBundle:Promotion:createPromo.html.twig")
     */
    public function updateAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();
        $pm = $this->get('cac_bar.promotion_manager');

        $entity = $em->getRepository('CacBarBundle:Bar')->find($id);
        $promotions = $entity->getPromotions();

        $promotionDummy = new PromotionDummy();
        $dummyJSON = $pm->toDummyJSON($promotions);
        $promotionDummy->setPromotion($dummyJSON);

        if (!$entity) {
            throw $this->createNotFoundException('Le bar demandé n\'existe pas.');
        }

        $editForm = $this->createEditForm($promotionDummy, $entity);
        $editForm->handleRequest($request);

        if ($editForm->isValid()) {
            $newPromotions = json_decode($request->request->get('cac_barbundle_promotion_dummy')['promotion'], true);
            foreach($promotions as $promotion) {
                $options = $promotion->getOptions();
                foreach($options as $option) {
                    $category = $option->getCategoryShortcode();
                    if($category == 'restriction') $category = 'condition';
                    $option->setValue($newPromotions[$promotion->getDay()][$promotion->getCategory()][$category]);
                    $em->persist($option);
                }
            }

            $em->flush();

            $user = $this->get('security.context')->getToken()->getUser();
            $plan = $em->getRepository('CacPaymentBundle:Payment')->findOneByUser($user);
            if ($plan != null) {
                $planName = $em->getRepository('CacPaymentBundle:Payment')->findOneByUser($user)->getPlan();
            }
            else
                $planName = "shooter";

            if ($planName === "shooter") {
                return $this->redirect($this->generateUrl('bars_abonnement', array('id' => $entity->getId())));
            }
            else
            {
                return $this->redirect($this->generateUrl('bars_offer', array('id' => $entity->getId())));
            }
        }

        return array(
            'bar'  => $entity,
            'form' => $editForm->createView()
        );
    }

    /**
     * Finds and displays a Bar entity.
     *
     * @Route("/{id}", name="promotion_show")
     * @Method("GET")
     * @Template()
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();
        $pm = $this->get('cac_bar.promotion_manager');
        $entity = $em->getRepository('CacBarBundle:Bar')->find($id);
        $restrictions = $em->getRepository('CacBarBundle:Restriction')->findAll();

        $promotions = $entity->getPromotions();
        $promotionDummy = new PromotionDummy();
        $dummyJSON = $pm->toDummyJSON($promotions);
        $promotionDummy->setPromotion($dummyJSON);

        $editForm = $this->createEditForm($promotionDummy, $entity);

        return array(
            'bar'      => $entity,
            'promotions' => json_decode($dummyJSON, true),
            'form'   => $editForm->createView(),
            'restrictions' => $restrictions
        );
    }

    /**
     * delete promo.
     *
     * @Route("/delete/{id}", name="delete_promo", options={"expose"=true})
     */
    public function deletePromoAction($id)
    {
        $em = $this->getDoctrine()->getManager();
        $promo = $em->getRepository('CacBarBundle:PromoOffertes')->find($id);
        $bar = $promo->getBar();
        $customer = $promo->getBar()->getAuthor();
        $user = $promo->getUser();
        $stripeApikey = $this->container->getParameter('stripe_api_key');
        $date = $promo->getCreatedAt()->format('d/m/Y');

        if($promo->getEtat() !== "non validé")
        {
            \Stripe\Stripe::setApiKey($stripeApikey);
            $payment = $em->getRepository('CacPaymentBundle:Payment')->findOneByUser($customer);
            $customerId = $payment->getCustomerId();
            \Stripe\InvoiceItem::create(array(
                "customer" => $customerId,
                "amount" => '-'.$customer->getGlassPrice() * $promo->getNbpersonne(),
                "currency" => "eur",
                "description" => "Réservation")
            );
        }
        $em->remove($promo);
        $em->flush();

        $md = $this->get('hip_mandrill.dispatcher');

        $message = new Message();
        $templateName = 'reservation-user-cancelled';
        $templateContent = array(
            array(
                'name' => 'barname',
                'content' => $bar->getName()
            ),
            array(
                'name' => 'reference',
                'content' => $promo->getReference()
            ),
            array(
                'name' => 'date',
                'content' => $date
            ),
        );
        $message
            ->addTo($user->getEmail(), $user->getFirstname().' '.$user->getName())
            ->setSubject('Confirmation d\'annulation : '.$bar->getName())
            ->setTrackOpens(true)
            ->setTrackClicks(true);

        $result = $md->send($message, $templateName, $templateContent);

        return new JsonResponse('Promo annulée');
    }
}