fixed bug in counting weiter games

fixed bug in counting weiter games

import model.SystemValues.WIN;
import model.db.DataObject;
import model.db.GameData;

public privileged aspect OverallStats {
    public OverallStatistics GameData.getOverallStatistics() {
        int anzahlSpieleGesamt = 0;
        int anzahlSpieleGesamtGewonnen = 0;
        int teuerstesRufspiel = 0;
        int teuerstesSolo = 0;
        int teuerstesSoloTout = 0;
        int teuerstesSoloSie = 0;
        int anzahlRufspiele = 0;
        int anzahlSoli = 0;
        int anzahlSoliTout = 0;
        int anzahlSoliSie = 0;
        int anzahlSoliGesamt = 0;
        int anzahlGewonneneSoliGesamt = 0;
        int anzahlGewonneneRufspiele = 0;
        int anzahlGewonneneSoli = 0;
        int anzahlGewonneneSoliTout = 0;
        int anzahlGewonneneSoliSie = 0;
        int anzahlWeiter = 0;
        double gesamtWinPerc = 0.0;
        double rufspieleWinPerc = 0.0;
        double soliGesamtWinPerc = 0.0;
        double soliNormalWinPerc = 0.0;
        double soliToutWinPerc = 0.0;
        double soliSieWinPerc = 0.0;

        for (DataObject obj : data) {
            switch (obj.getGameKind()) {
            case RUFSPIEL:
                anzahlRufspiele++;
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneRufspiele++;
                    anzahlSpieleGesamtGewonnen++;
                }
                if (obj.getGameValue() > teuerstesRufspiel) {
                    teuerstesRufspiel = obj.getGameValue();
                }
                break;
            case SOLO:
                anzahlSoli++;
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneSoli++;
                    anzahlSpieleGesamtGewonnen++;
                }
                if (obj.getGameValue() > teuerstesSolo) {
                    teuerstesSolo = obj.getGameValue();
                }
                break;
            case TOUT:
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneSoliTout++;
                    anzahlSpieleGesamtGewonnen++;
                }
                if (obj.getGameValue() > teuerstesSoloTout) {
                    teuerstesSoloTout = obj.getGameValue();
                }
                anzahlSoliTout++;
                break;
            case SIE:
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneSoliSie++;
                    anzahlSpieleGesamtGewonnen++;
                }
                anzahlSoliSie++;
                if (obj.getGameValue() > teuerstesSoloSie) {
                    teuerstesSoloSie = obj.getGameValue();
                }
                break;
            case WEITER:
                anzahlWeiter++;
                break;
            case NONE: // nothing to do here
                break;
            default: // here neither
                break;
            }
        }

        anzahlSoliGesamt = anzahlSoli + anzahlSoliTout + anzahlSoliSie;
        anzahlGewonneneSoliGesamt = anzahlGewonneneSoli
                + anzahlGewonneneSoliSie + anzahlGewonneneSoliTout;

        gesamtWinPerc = (anzahlSpieleGesamt > 0 ? anzahlSpieleGesamtGewonnen
                / ((double) anzahlSpieleGesamt) : 0) * 100;
        rufspieleWinPerc = (anzahlRufspiele > 0 ? anzahlGewonneneRufspiele
                / ((double) anzahlRufspiele) : 0) * 100;
        soliGesamtWinPerc = ((anzahlSoli + anzahlSoliSie + anzahlSoliTout) > 0 ? ((anzahlGewonneneSoli
                + anzahlGewonneneSoliTout + anzahlSoliSie) / 1.0 / (anzahlSoli
                + anzahlSoliSie + anzahlSoliTout))
                : 0) * 100;
        soliNormalWinPerc = (anzahlSoli > 0 ? anzahlGewonneneSoli
                / ((double) anzahlSoli) : 0) * 100;
        soliToutWinPerc = (anzahlSoliTout > 0 ? anzahlGewonneneSoliTout
                / ((double) anzahlSoliTout) : 0) * 100;
        soliSieWinPerc = (anzahlSoliSie > 0 ? anzahlSoliSie
                / ((double) anzahlSoliSie) : 0) * 100;

        return new OverallStatistics(anzahlSpieleGesamt,
                anzahlSpieleGesamtGewonnen, anzahlRufspiele,
                anzahlGewonneneRufspiele, anzahlSoli, anzahlGewonneneSoli,
                anzahlSoliTout, anzahlGewonneneSoliTout, anzahlSoliSie,
                anzahlGewonneneSoliSie, anzahlSoliGesamt,
                anzahlGewonneneSoliGesamt, anzahlWeiter, teuerstesRufspiel,
                teuerstesSolo, teuerstesSoloTout, teuerstesSoloSie,
                gesamtWinPerc, rufspieleWinPerc, soliGesamtWinPerc,
                soliNormalWinPerc, soliToutWinPerc, soliSieWinPerc);
    }
}

class OverallStatistics {
    private int anzahlSpieleGesamt;
    private int anzahlSpieleGesamtGewonnen;
    private int anzahlRufspiele;
    private int anzahlGewonneneRufspiele;
    private int anzahlSoli;
    private int anzahlGewonneneSoli;
    private int anzahlSoliTout;
    private int anzahlGewonneneSoliTout;
    private int anzahlSoliSie;
    private int anzahlGewonneneSoliSie;
    private int anzahlSoliGesamt;
    private int anzahlGewonneneSoliGesamt;
    private int anzahlWeiter;
    private int teuerstesRufspiel = 0;
    private int teuerstesSolo = 0;
    private int teuerstesSoloTout = 0;
    private int teuerstesSoloSie = 0;
    private double gesamtWinPerc = 0.0;
    private double rufspieleWinPerc = 0.0;
    private double soliGesamtWinPerc = 0.0;
    private double soliNormalWinPerc = 0.0;
    private double soliToutWinPerc = 0.0;
    private double soliSieWinPerc = 0.0;

    public OverallStatistics(int anzahlSpieleGesamt,
            int anzahlSpieleGesamtGewonnen, int anzahlRufspiele,
            int anzahlGewonneneRufspiele, int anzahlSoli,
            int anzahlGewonneneSoli, int anzahlSoliTout,
            int anzahlGewonneneSoliTout, int anzahlSoliSie,
            int anzahlGewonneneSoliSie, int anzahlSoliGesamt,
            int anzahlGewonneneSoliGesamt, int anzahlWeiter,
            int teuerstesRufspiel, int teuerstesSolo, int teuerstesSoloTout,
            int teuerstesSoloSie, double gesamtWinPerc,
            double rufspieleWinPerc, double soliGesamtWinPerc,
            double soliNormalWinPerc, double soliToutWinPerc,
            double soliSieWinPerc) {
        this.anzahlSpieleGesamt = anzahlSpieleGesamt;
        this.anzahlSpieleGesamtGewonnen = anzahlSpieleGesamtGewonnen;
        this.anzahlRufspiele = anzahlRufspiele;
        this.anzahlGewonneneRufspiele = anzahlGewonneneRufspiele;
        this.anzahlSoli = anzahlSoli;
        this.anzahlGewonneneSoli = anzahlGewonneneSoli;
        this.anzahlSoliTout = anzahlSoliTout;
        this.anzahlGewonneneSoliTout = anzahlGewonneneSoliTout;
        this.anzahlSoliSie = anzahlSoliSie;
        this.anzahlGewonneneSoliSie = anzahlGewonneneSoliSie;
        this.anzahlSoliGesamt = anzahlSoliGesamt;
        this.anzahlGewonneneSoliGesamt = anzahlGewonneneSoliGesamt;
        this.anzahlWeiter = anzahlWeiter;
        this.teuerstesRufspiel = teuerstesRufspiel;
        this.teuerstesSolo = teuerstesSolo;
        this.teuerstesSoloTout = teuerstesSoloTout;
        this.teuerstesSoloSie = teuerstesSoloSie;
        this.gesamtWinPerc = gesamtWinPerc;
        this.rufspieleWinPerc = rufspieleWinPerc;
        this.soliGesamtWinPerc = soliGesamtWinPerc;
        this.soliNormalWinPerc = soliNormalWinPerc;
        this.soliToutWinPerc = soliToutWinPerc;
        this.soliSieWinPerc = soliSieWinPerc;
    }

    public int getAnzahlSpieleGesamt() {
        return anzahlSpieleGesamt;
    }

    public int getAnzahlSpieleGesamtGewonnen() {
        return anzahlSpieleGesamtGewonnen;
    }

    public int getAnzahlRufspiele() {
        return anzahlRufspiele;
    }

    public int getAnzahlGewonneneRufspiele() {
        return anzahlGewonneneRufspiele;
    }

    public int getAnzahlSoli() {
        return anzahlSoli;
    }

    public int getAnzahlGewonneneSoli() {
        return anzahlGewonneneSoli;
    }

    public int getAnzahlSoliTout() {
        return anzahlSoliTout;
    }

    public int getAnzahlGewonneneSoliTout() {
        return anzahlGewonneneSoliTout;
    }

    public int getAnzahlSoliSie() {
        return anzahlSoliSie;
    }

    public int getAnzahlGewonneneSoliSie() {
        return anzahlGewonneneSoliSie;
    }

    public int getAnzahlSoliGesamt() {
        return anzahlSoliGesamt;
    }

    public int getAnzahlGewonneneSoliGesamt() {
        return anzahlGewonneneSoliGesamt;
    }

    public int getAnzahlWeiter() {
        return anzahlWeiter;
    }

    public int getTeuerstesRufspiel() {
        return teuerstesRufspiel;
    }

    public int getTeuerstesSolo() {
        return teuerstesSolo;
    }

    public int getTeuerstesSoloTout() {
        return teuerstesSoloTout;
    }

    public int getTeuerstesSoloSie() {
        return teuerstesSoloSie;
    }

    public double getGesamtWinPerc() {
        return gesamtWinPerc;
    }

    public double getRufspieleWinPerc() {
        return rufspieleWinPerc;
    }

    public double getSoliGesamtWinPerc() {
        return soliGesamtWinPerc;
    }

    public double getSoliNormalWinPerc() {
        return soliNormalWinPerc;
    }

    public double getSoliToutWinPerc() {
        return soliToutWinPerc;
    }

    public double getSoliSieWinPerc() {
        return soliSieWinPerc;
    }
}

import model.SystemValues.WIN;
import model.db.DataObject;
import model.db.GameData;

public privileged aspect OverallStats {
    public OverallStatistics GameData.getOverallStatistics() {
        int anzahlSpieleGesamt = 0;
        int anzahlSpieleGesamtGewonnen = 0;
        int teuerstesRufspiel = 0;
        int teuerstesSolo = 0;
        int teuerstesSoloTout = 0;
        int teuerstesSoloSie = 0;
        int anzahlRufspiele = 0;
        int anzahlSoli = 0;
        int anzahlSoliTout = 0;
        int anzahlSoliSie = 0;
        int anzahlSoliGesamt = 0;
        int anzahlGewonneneSoliGesamt = 0;
        int anzahlGewonneneRufspiele = 0;
        int anzahlGewonneneSoli = 0;
        int anzahlGewonneneSoliTout = 0;
        int anzahlGewonneneSoliSie = 0;
        int anzahlWeiter = -1;
        double gesamtWinPerc = 0.0;
        double rufspieleWinPerc = 0.0;
        double soliGesamtWinPerc = 0.0;
        double soliNormalWinPerc = 0.0;
        double soliToutWinPerc = 0.0;
        double soliSieWinPerc = 0.0;

        for (DataObject obj : data) {
            switch (obj.getGameKind()) {
            case RUFSPIEL:
                anzahlRufspiele++;
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneRufspiele++;
                    anzahlSpieleGesamtGewonnen++;
                }
                if (obj.getGameValue() > teuerstesRufspiel) {
                    teuerstesRufspiel = obj.getGameValue();
                }
                break;
            case SOLO:
                anzahlSoli++;
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneSoli++;
                    anzahlSpieleGesamtGewonnen++;
                }
                if (obj.getGameValue() > teuerstesSolo) {
                    teuerstesSolo = obj.getGameValue();
                }
                break;
            case TOUT:
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneSoliTout++;
                    anzahlSpieleGesamtGewonnen++;
                }
                if (obj.getGameValue() > teuerstesSoloTout) {
                    teuerstesSoloTout = obj.getGameValue();
                }
                anzahlSoliTout++;
                break;
            case SIE:
                anzahlSpieleGesamt++;
                if (obj.getGameWon() == WIN.PLAYER) {
                    anzahlGewonneneSoliSie++;
                    anzahlSpieleGesamtGewonnen++;
                }
                anzahlSoliSie++;
                if (obj.getGameValue() > teuerstesSoloSie) {
                    teuerstesSoloSie = obj.getGameValue();
                }
                break;
            case WEITER:
                anzahlWeiter++;
                break;
            case NONE: // nothing to do here
                break;
            default: // here neither
                break;
            }
        }

        anzahlSoliGesamt = anzahlSoli + anzahlSoliTout + anzahlSoliSie;
        anzahlGewonneneSoliGesamt = anzahlGewonneneSoli
                + anzahlGewonneneSoliSie + anzahlGewonneneSoliTout;

        gesamtWinPerc = (anzahlSpieleGesamt > 0 ? anzahlSpieleGesamtGewonnen
                / ((double) anzahlSpieleGesamt) : 0) * 100;
        rufspieleWinPerc = (anzahlRufspiele > 0 ? anzahlGewonneneRufspiele
                / ((double) anzahlRufspiele) : 0) * 100;
        soliGesamtWinPerc = ((anzahlSoli + anzahlSoliSie + anzahlSoliTout) > 0 ? ((anzahlGewonneneSoli
                + anzahlGewonneneSoliTout + anzahlSoliSie) / 1.0 / (anzahlSoli
                + anzahlSoliSie + anzahlSoliTout))
                : 0) * 100;
        soliNormalWinPerc = (anzahlSoli > 0 ? anzahlGewonneneSoli
                / ((double) anzahlSoli) : 0) * 100;
        soliToutWinPerc = (anzahlSoliTout > 0 ? anzahlGewonneneSoliTout
                / ((double) anzahlSoliTout) : 0) * 100;
        soliSieWinPerc = (anzahlSoliSie > 0 ? anzahlSoliSie
                / ((double) anzahlSoliSie) : 0) * 100;

        return new OverallStatistics(anzahlSpieleGesamt,
                anzahlSpieleGesamtGewonnen, anzahlRufspiele,
                anzahlGewonneneRufspiele, anzahlSoli, anzahlGewonneneSoli,
                anzahlSoliTout, anzahlGewonneneSoliTout, anzahlSoliSie,
                anzahlGewonneneSoliSie, anzahlSoliGesamt,
                anzahlGewonneneSoliGesamt, anzahlWeiter, teuerstesRufspiel,
                teuerstesSolo, teuerstesSoloTout, teuerstesSoloSie,
                gesamtWinPerc, rufspieleWinPerc, soliGesamtWinPerc,
                soliNormalWinPerc, soliToutWinPerc, soliSieWinPerc);
    }
}

class OverallStatistics {
    private int anzahlSpieleGesamt;
    private int anzahlSpieleGesamtGewonnen;
    private int anzahlRufspiele;
    private int anzahlGewonneneRufspiele;
    private int anzahlSoli;
    private int anzahlGewonneneSoli;
    private int anzahlSoliTout;
    private int anzahlGewonneneSoliTout;
    private int anzahlSoliSie;
    private int anzahlGewonneneSoliSie;
    private int anzahlSoliGesamt;
    private int anzahlGewonneneSoliGesamt;
    private int anzahlWeiter;
    private int teuerstesRufspiel = 0;
    private int teuerstesSolo = 0;
    private int teuerstesSoloTout = 0;
    private int teuerstesSoloSie = 0;
    private double gesamtWinPerc = 0.0;
    private double rufspieleWinPerc = 0.0;
    private double soliGesamtWinPerc = 0.0;
    private double soliNormalWinPerc = 0.0;
    private double soliToutWinPerc = 0.0;
    private double soliSieWinPerc = 0.0;

    public OverallStatistics(int anzahlSpieleGesamt,
            int anzahlSpieleGesamtGewonnen, int anzahlRufspiele,
            int anzahlGewonneneRufspiele, int anzahlSoli,
            int anzahlGewonneneSoli, int anzahlSoliTout,
            int anzahlGewonneneSoliTout, int anzahlSoliSie,
            int anzahlGewonneneSoliSie, int anzahlSoliGesamt,
            int anzahlGewonneneSoliGesamt, int anzahlWeiter,
            int teuerstesRufspiel, int teuerstesSolo, int teuerstesSoloTout,
            int teuerstesSoloSie, double gesamtWinPerc,
            double rufspieleWinPerc, double soliGesamtWinPerc,
            double soliNormalWinPerc, double soliToutWinPerc,
            double soliSieWinPerc) {
        this.anzahlSpieleGesamt = anzahlSpieleGesamt;
        this.anzahlSpieleGesamtGewonnen = anzahlSpieleGesamtGewonnen;
        this.anzahlRufspiele = anzahlRufspiele;
        this.anzahlGewonneneRufspiele = anzahlGewonneneRufspiele;
        this.anzahlSoli = anzahlSoli;
        this.anzahlGewonneneSoli = anzahlGewonneneSoli;
        this.anzahlSoliTout = anzahlSoliTout;
        this.anzahlGewonneneSoliTout = anzahlGewonneneSoliTout;
        this.anzahlSoliSie = anzahlSoliSie;
        this.anzahlGewonneneSoliSie = anzahlGewonneneSoliSie;
        this.anzahlSoliGesamt = anzahlSoliGesamt;
        this.anzahlGewonneneSoliGesamt = anzahlGewonneneSoliGesamt;
        this.anzahlWeiter = anzahlWeiter;
        this.teuerstesRufspiel = teuerstesRufspiel;
        this.teuerstesSolo = teuerstesSolo;
        this.teuerstesSoloTout = teuerstesSoloTout;
        this.teuerstesSoloSie = teuerstesSoloSie;
        this.gesamtWinPerc = gesamtWinPerc;
        this.rufspieleWinPerc = rufspieleWinPerc;
        this.soliGesamtWinPerc = soliGesamtWinPerc;
        this.soliNormalWinPerc = soliNormalWinPerc;
        this.soliToutWinPerc = soliToutWinPerc;
        this.soliSieWinPerc = soliSieWinPerc;
    }

    public int getAnzahlSpieleGesamt() {
        return anzahlSpieleGesamt;
    }

    public int getAnzahlSpieleGesamtGewonnen() {
        return anzahlSpieleGesamtGewonnen;
    }

    public int getAnzahlRufspiele() {
        return anzahlRufspiele;
    }

    public int getAnzahlGewonneneRufspiele() {
        return anzahlGewonneneRufspiele;
    }

    public int getAnzahlSoli() {
        return anzahlSoli;
    }

    public int getAnzahlGewonneneSoli() {
        return anzahlGewonneneSoli;
    }

    public int getAnzahlSoliTout() {
        return anzahlSoliTout;
    }

    public int getAnzahlGewonneneSoliTout() {
        return anzahlGewonneneSoliTout;
    }

    public int getAnzahlSoliSie() {
        return anzahlSoliSie;
    }

    public int getAnzahlGewonneneSoliSie() {
        return anzahlGewonneneSoliSie;
    }

    public int getAnzahlSoliGesamt() {
        return anzahlSoliGesamt;
    }

    public int getAnzahlGewonneneSoliGesamt() {
        return anzahlGewonneneSoliGesamt;
    }

    public int getAnzahlWeiter() {
        return anzahlWeiter;
    }

    public int getTeuerstesRufspiel() {
        return teuerstesRufspiel;
    }

    public int getTeuerstesSolo() {
        return teuerstesSolo;
    }

    public int getTeuerstesSoloTout() {
        return teuerstesSoloTout;
    }

    public int getTeuerstesSoloSie() {
        return teuerstesSoloSie;
    }

    public double getGesamtWinPerc() {
        return gesamtWinPerc;
    }

    public double getRufspieleWinPerc() {
        return rufspieleWinPerc;
    }

    public double getSoliGesamtWinPerc() {
        return soliGesamtWinPerc;
    }

    public double getSoliNormalWinPerc() {
        return soliNormalWinPerc;
    }

    public double getSoliToutWinPerc() {
        return soliToutWinPerc;
    }

    public double getSoliSieWinPerc() {
        return soliSieWinPerc;
    }
}


Revert 80c455f312db210dad581ae50042cc437dc56dbd

package org.slc.sli.aspect;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.CollectionOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.Repository;
import org.slc.sli.dal.repository.MongoRepository;

import org.slc.sli.common.util.logging.SecurityEvent;
import org.slc.sli.common.util.logging.LoggerCarrier;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

public aspect LoggerCarrierAspect {
	declare parents : (org.slc.sli.ingestion..* &&
            !java.lang.Enum+)  implements LoggerCarrier;

    private Repository<Entity> entityRepository;

    @Value("${sli.ingestion.securityEvent.capSize}")
    private String capSize;

    public void LoggerCarrier.audit(SecurityEvent event) {
        MongoRepository<Entity> mer = (MongoRepository<Entity>) LoggerCarrierAspect.aspectOf().getEntityRepository();
        if (mer != null) {
            MongoTemplate mongoTemplate = mer.getTemplate();
            String capSizeStr = LoggerCarrierAspect.aspectOf().getCapSize();

            if (capSizeStr != null && !capSizeStr.isEmpty()) {
                int capSizeInt = Integer.parseInt(capSizeStr);
                // UN: If the collection is not present, create the capped collection.
                // However, if it is present and uncapped, change it to capped collection
                // 496 bytes is size of 1 security event document * capsize ~ the size that we want.
                if (!mongoTemplate.collectionExists("securityEvent")) {
                    CollectionOptions collectionOptions = new CollectionOptions(capSizeInt * 496, capSizeInt, true);
                    mongoTemplate.createCollection("securityEvent", collectionOptions);
                } else {
                    if (!mongoTemplate.getCollection("securityEvent").isCapped()) {
                        DBObject cmd = new BasicDBObject();
                        cmd.put("convertToCapped", "securityEvent");
                        cmd.put("size", capSizeInt * 496);
                        mongoTemplate.getDb().command(cmd);
                    }
                }
            }

            Map<String, Object> metadata = new HashMap<String, Object>();
            metadata.put("tenantId", event.getTenantId());
            mer.create("securityEvent", event.getProperties(), metadata, "securityEvent");
        } else {
            LoggerFactory.getLogger("SecurityMonitor").info("[Could not log SecurityEvent to mongo!]");
        }

        switch (event.getLogLevel()) {
            case TYPE_DEBUG:
                LoggerFactory.getLogger("SecurityMonitor").debug(event.toString());
                break;

            case TYPE_WARN:
                LoggerFactory.getLogger("SecurityMonitor").warn(event.toString());
                break;

            case TYPE_INFO:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;

            case TYPE_ERROR:
                LoggerFactory.getLogger("SecurityMonitor").error(event.toString());
                break;

            case TYPE_TRACE:
                LoggerFactory.getLogger("SecurityMonitor").trace(event.toString());
                break;

            default:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;
        }
    }

    public Repository<Entity> getEntityRepository() {
        return entityRepository;
    }

    public void setEntityRepository(Repository<Entity> entityRepository) {
        this.entityRepository = entityRepository;
    }

    public String getCapSize() {
        return capSize;
    }

    public void setCapSize(String capSize) {
        this.capSize = capSize;
    }

}

package org.slc.sli.aspect;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.CollectionOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.Repository;
import org.slc.sli.dal.repository.MongoRepository;

import org.slc.sli.common.util.logging.SecurityEvent;
import org.slc.sli.common.util.logging.LoggerCarrier;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

public aspect LoggerCarrierAspect {
	declare parents : (org.slc.sli.ingestion..* &&
            !java.lang.Enum+)  implements LoggerCarrier;

    private Repository<Entity> entityRepository;

//    private MongoTemplate template;

//    public MongoTemplate getTemplate() {
//    	return template;
//    }

//    public void setTemplate(MongoTemplate template) {
//    	this.template = template;
//    }

    @Value("${sli.ingestion.securityEvent.capSize}")
    private String capSize;

    public void LoggerCarrier.audit(SecurityEvent event) {
        MongoRepository<Entity> mer = (MongoRepository<Entity>) LoggerCarrierAspect.aspectOf().getEntityRepository();
        if (mer != null) {
            MongoTemplate mongoTemplate = mer.getTemplate();
            String capSizeStr = LoggerCarrierAspect.aspectOf().getCapSize();

            if (capSizeStr != null && !capSizeStr.isEmpty()) {
                int capSizeInt = Integer.parseInt(capSizeStr);
                // UN: If the collection is not present, create the capped collection.
                // However, if it is present and uncapped, change it to capped collection
                // 496 bytes is size of 1 security event document * capsize ~ the size that we want.
                if (!mongoTemplate.collectionExists("securityEvent")) {
                    CollectionOptions collectionOptions = new CollectionOptions(capSizeInt * 496, capSizeInt, true);
                    mongoTemplate.createCollection("securityEvent", collectionOptions);
                } else {
                    if (!mongoTemplate.getCollection("securityEvent").isCapped()) {
                        DBObject cmd = new BasicDBObject();
                        cmd.put("convertToCapped", "securityEvent");
                        cmd.put("size", capSizeInt * 496);
                        mongoTemplate.getDb().command(cmd);
                    }
                }
            }

            Map<String, Object> metadata = new HashMap<String, Object>();
            metadata.put("tenantId", event.getTenantId());
            mer.create("securityEvent", event.getProperties(), metadata, "securityEvent");
        } else {
            LoggerFactory.getLogger("SecurityMonitor").info("[Could not log SecurityEvent to mongo!]");
        }

        switch (event.getLogLevel()) {
            case TYPE_DEBUG:
                LoggerFactory.getLogger("SecurityMonitor").debug(event.toString());
                break;

            case TYPE_WARN:
                LoggerFactory.getLogger("SecurityMonitor").warn(event.toString());
                break;

            case TYPE_INFO:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;

            case TYPE_ERROR:
                LoggerFactory.getLogger("SecurityMonitor").error(event.toString());
                break;

            case TYPE_TRACE:
                LoggerFactory.getLogger("SecurityMonitor").trace(event.toString());
                break;

            default:
                LoggerFactory.getLogger("SecurityMonitor").info(event.toString());
                break;
        }
    }

    public Repository<Entity> getEntityRepository() {
        return entityRepository;
    }

    public void setEntityRepository(Repository<Entity> entityRepository) {
        this.entityRepository = entityRepository;
    }

    public String getCapSize() {
        return capSize;
    }

    public void setCapSize(String capSize) {
        this.capSize = capSize;
    }

}


CThread2 renamed to CThread

CThread2 renamed to CThread

import properties.Property;
import properties.competition.JavaMOP;
import structure.impl.other.Verdict;
import benchmark.competition.java.QEAMonitoringAspect;

public aspect JavaMOPThreeAspect extends QEAMonitoringAspect {

	private final int A = 1;
	private final int B = 2;
	private final int C = 3;

	public JavaMOPThreeAspect() {
		super(new JavaMOP().make(Property.JAVAMOP_THREE));
		validationMsg = "Property JavaMOP 3 satisfied";
		violationMsg = "Property JavaMOP 3 violated. The functions A(), B(), C() must be called equal times";
	}

	pointcut A() : call(void CThread.A());

	pointcut B() : call(void CThread.B());

	pointcut C() : call(void CThread.C());

	before() : A() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(A);
		}
		if (verdict == Verdict.FAILURE) {
			System.err.println(violationMsg);
			printTimeAndExit();
		}
	}

	before() : B() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(B);
		}
		if (verdict == Verdict.FAILURE) {
			System.err.println(violationMsg);
			printTimeAndExit();
		}
	}

	before() : C() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(C);
		}
		if (verdict == Verdict.FAILURE) {
			System.err.println(violationMsg);
			printTimeAndExit();
		}
	}
}

import properties.Property;
import properties.competition.JavaMOP;
import structure.impl.other.Verdict;
import benchmark.competition.java.QEAMonitoringAspect;

public aspect JavaMOPThreeAspect extends QEAMonitoringAspect {

	private final int A = 1;
	private final int B = 2;
	private final int C = 3;

	public JavaMOPThreeAspect() {
		super(new JavaMOP().make(Property.JAVAMOP_THREE));
		validationMsg = "Property JavaMOP 3 satisfied";
		violationMsg = "Property JavaMOP 3 violated. The functions A(), B(), C() must be called equal times";
	}

	pointcut A() : call(void CThread2.A());

	pointcut B() : call(void CThread2.B());

	pointcut C() : call(void CThread2.C());

	before() : A() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(A);
		}
		if (verdict == Verdict.FAILURE) {
			System.err.println(violationMsg);
			printTimeAndExit();
		}
	}

	before() : B() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(B);
		}
		if (verdict == Verdict.FAILURE) {
			System.err.println(violationMsg);
			printTimeAndExit();
		}
	}

	before() : C() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(C);
		}
		if (verdict == Verdict.FAILURE) {
			System.err.println(violationMsg);
			printTimeAndExit();
		}
	}
}


Aspect Tryouts

Aspect Tryouts

import java.util.*;

public aspect MethodInterceptor {
      Stack<String> st = new Stack<String>();

	//pointcut traced() : !within(MethodInterceptor) && execution(public * *.*(..)) ;
	pointcut traced() : !within(MethodInterceptor) && execution( * *.*(..)) && !initialization(*.new(..));
private String previousClass;
private String currentClass;
private int callDepth=1;

	before() : traced() {

String prefix=null;
			if(callDepth==1){
        prefix="NEW_CALL:";

		}
		else{
		prefix="NESTED_CALL:";

		}
		Object o = thisJoinPoint.getThis();
        String currentClassName=null;
        if(o!=null){
        currentClassName=o.getClass().getName();
        }
        else{
      String signature=  thisJoinPointStaticPart.getSignature().toString();

      String array[]=signature.split("\\s");
         String methodName=array[1];
System.out.println(signature);
         if(methodName.contains("."))
         currentClassName=methodName.split("\\.")[0];
System.out.println(currentClassName);

        }
        String sender=null;

        if(previousClass==null){
        previousClass=currentClassName;
        sender=currentClassName;
	    }
       else  if(previousClass.equals(currentClassName)){
        sender=currentClassName;

        }
        else{
        sender=previousClass;
        }

      String call=  thisJoinPointStaticPart.getSignature().toString();

      String array[]=call.split("\\s");
      String methodName=array[1];
      String returnType=array[0];

      if(methodName.contains(".")){
      methodName=methodName.split("\\.")[1];
      }
      if(st.size()>0){

      sender=st.peek();
      }

      String methodCall=methodName+":"+returnType;

//System.out.println(callDepth+"::::"+prefix+":::: "+sender+"------>" + methodCall+"---->"+currentClassName);
System.out.println(sender+"->"+currentClassName+":"+methodCall);

currentClass=currentClassName;

       st.push(currentClass);

previousClass=currentClass;
		callDepth++;

	}

	after() : traced() {
		callDepth--;

      st.pop();

		//currentClass=previousClass;
	}

	private void print(String prefix, Object message) {

		if(callDepth==1){

					System.out.print("NEW_CALL:   "+callDepth+":"+message);

		}
		else{
				System.out.print("NESTED_CALL"+callDepth+message);

		}

		//System.out.println(prefix + ": " + message);
	}
}

public aspect MethodInterceptor {

	//pointcut traced() : !within(MethodInterceptor) && execution(public * *.*(..)) ;
	pointcut traced() : !within(MethodInterceptor) && execution( * *.*(..)) && !initialization(*.new(..));
private String previousClass;
private String currentClass;
private int callDepth=1;

	before() : traced() {

String prefix=null;
			if(callDepth==1){
        prefix="NEW_CALL:";

		}
		else{
		prefix="NESTED_CALL:";

		}
		Object o = thisJoinPoint.getThis();
        String currentClassName=null;
        if(o!=null){
        currentClassName=o.getClass().getName();
        }
        else{
      String signature=  thisJoinPointStaticPart.getSignature().toString();

      String array[]=signature.split("\\s");
         String methodName=array[1];
System.out.println(signature);
         if(methodName.contains("."))
         currentClassName=methodName.split("\\.")[0];
System.out.println(currentClassName);

        }
        String sender=null;

        if(previousClass==null){
        previousClass=currentClassName;
        sender=currentClassName;
	    }
       else  if(previousClass.equals(currentClassName)){
        sender=currentClassName;

        }
        else{
        sender=previousClass;
        }

      String call=  thisJoinPointStaticPart.getSignature().toString();

      String array[]=call.split("\\s");
      String methodName=array[1];
      String returnType=array[0];

      if(methodName.contains(".")){
      methodName=methodName.split("\\.")[1];
      }

      String methodCall=methodName+":"+returnType;

//System.out.println(callDepth+"::::"+prefix+":::: "+sender+"------>" + methodCall+"---->"+currentClassName);
System.out.println(sender+"->"+currentClassName+":"+methodCall);

currentClass=currentClassName;
previousClass=currentClass;
		callDepth++;

	}

	after() : traced() {
		callDepth--;

		currentClass=previousClass;
	}

	private void print(String prefix, Object message) {

		if(callDepth==1){

					System.out.print("NEW_CALL:   "+callDepth+":"+message);

		}
		else{
				System.out.print("NESTED_CALL"+callDepth+message);

		}

		//System.out.println(prefix + ": " + message);
	}
}


* change comment

* change comment

package ru.agentlab.maia.context.aj;

import ru.agentlab.maia.context.IMaiaContext;

/**
 * Abstract aspect with pointcuts of {@link IMaiaContext} methods
 *
 * @author Shishkin Dmitriy
 *
 */
public abstract aspect AMaiaContext {

	/**
	 * When actual {@link IMaiaContext} object is created
	 */
	public pointcut onConstruct() :
		execution(IMaiaContext+.new(..));

	/**
	 * When {@link IMaiaContext} get service object by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service
	 */
	public pointcut onGetByString(IMaiaContext context, String id) :
		execution(Object IMaiaContext+.get(String)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} get service object by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 */
	public pointcut onGetByClass(IMaiaContext context, Class<?> id) :
		execution(Object IMaiaContext+.get(Class)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} set service object by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service
	 * @param obj
	 *            - service object
	 */
	public pointcut onSetByString(IMaiaContext context, String id, Object obj) :
		execution(void IMaiaContext+.set(String, Object)) &&
		target(context) &&
		args(id, obj);

	/**
	 * When {@link IMaiaContext} set service object by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 * @param obj
	 *            - service object
	 */
	public pointcut onSetByClass(IMaiaContext context, Class<?> id,
			Object obj) :
		execution(void IMaiaContext+.set(Class, Object)) &&
		target(context) &&
		args(id, obj);

	/**
	 * When {@link IMaiaContext} get service object locally by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service
	 */
	public pointcut onGetLocalByString(IMaiaContext context, String id) :
		execution(Object IMaiaContext+.getLocal(String)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} get service object locally by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 */
	public pointcut onGetLocalByClass(IMaiaContext context, Class<?> id) :
		execution(Object IMaiaContext+.getLocal(Class)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} remove service object by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service to be removed
	 */
	public pointcut onRemoveByString(IMaiaContext context, String id) :
		execution(void IMaiaContext+.remove(String)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} remove service object by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 */
	public pointcut onRemoveByClass(IMaiaContext context, Class<?> id) :
		execution(void IMaiaContext+.remove(Class)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} retrieve all it's childs contexts
	 *
	 * @param context
	 *            - current context
	 */
	public pointcut onGetChilds(IMaiaContext context) :
		execution(Iterable<IMaiaContext>  IMaiaContext+.getChilds()) &&
		target(context);

	/**
	 * When {@link IMaiaContext} retrieve parent context
	 *
	 * @param context
	 *            - current context
	 */
	public pointcut onGetParent(IMaiaContext context) :
		execution(IMaiaContext IMaiaContext+.getParent(..)) &&
		target(context);

}

package ru.agentlab.maia.context.aj;

import ru.agentlab.maia.context.IMaiaContext;

/**
 * Abstract aspect with pointcuts of {@link IMaiaContext} methods
 *
 * @author Shishkin Dmitriy
 *
 */
public abstract aspect AMaiaContext {

	/**
	 * When actual IMaiaContext object is created
	 */
	public pointcut onConstruct() :
		execution(IMaiaContext+.new(..));

	/**
	 * When {@link IMaiaContext} get service object by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service
	 */
	public pointcut onGetByString(IMaiaContext context, String id) :
		execution(Object IMaiaContext+.get(String)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} get service object by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 */
	public pointcut onGetByClass(IMaiaContext context, Class<?> id) :
		execution(Object IMaiaContext+.get(Class)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} set service object by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service
	 * @param obj
	 *            - service object
	 */
	public pointcut onSetByString(IMaiaContext context, String id, Object obj) :
		execution(void IMaiaContext+.set(String, Object)) &&
		target(context) &&
		args(id, obj);

	/**
	 * When {@link IMaiaContext} set service object by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 * @param obj
	 *            - service object
	 */
	public pointcut onSetByClass(IMaiaContext context, Class<?> id,
			Object obj) :
		execution(void IMaiaContext+.set(Class, Object)) &&
		target(context) &&
		args(id, obj);

	/**
	 * When {@link IMaiaContext} get service object locally by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service
	 */
	public pointcut onGetLocalByString(IMaiaContext context, String id) :
		execution(Object IMaiaContext+.getLocal(String)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} get service object locally by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 */
	public pointcut onGetLocalByClass(IMaiaContext context, Class<?> id) :
		execution(Object IMaiaContext+.getLocal(Class)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} remove service object by string identifier
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - string identifier of context service to be removed
	 */
	public pointcut onRemoveByString(IMaiaContext context, String id) :
		execution(void IMaiaContext+.remove(String)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} remove service object by it's type
	 *
	 * @param context
	 *            - current context
	 * @param id
	 *            - type of context service
	 */
	public pointcut onRemoveByClass(IMaiaContext context, Class<?> id) :
		execution(void IMaiaContext+.remove(Class)) &&
		target(context) &&
		args(id);

	/**
	 * When {@link IMaiaContext} retrieve all it's childs contexts
	 *
	 * @param context
	 *            - current context
	 */
	public pointcut onGetChilds(IMaiaContext context) :
		execution(Iterable<IMaiaContext>  IMaiaContext+.getChilds()) &&
		target(context);

	/**
	 * When {@link IMaiaContext} retrieve parent context
	 *
	 * @param context
	 *            - current context
	 */
	public pointcut onGetParent(IMaiaContext context) :
		execution(IMaiaContext IMaiaContext+.getParent(..)) &&
		target(context);

}


attempt to fix npe

attempt to fix npe

package de.cosmocode.palava.jpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;

import de.cosmocode.palava.ipc.IpcConnection;

public final aspect TransactionAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(TransactionAspect.class);

    private Provider<EntityManager> currentManager;
    private Provider<IpcConnection> currentConnection;

    @Inject
    public void setProvider(Provider<EntityManager> manager, Provider<IpcConnection> connection) {
        this.currentManager = Preconditions.checkNotNull(manager, "Manager");
        this.currentConnection = Preconditions.checkNotNull(connection, "Connection");
    }

    pointcut createInjector(): call(Injector Guice.createInjector(..));

    @SuppressAjWarnings("adviceDidNotMatch")
    after() returning (Injector injector): createInjector() {
        LOG.trace("Injecting members on {}", this);
        if (currentManager == null) {
            injector.injectMembers(this);
        } else {
            throw new IllegalStateException("An injector has already been created");
        }
    }

    pointcut transactional(): execution(@Transactional * *.*(..));

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final IpcConnection connection = currentConnection.get();
        final Key<EntityManager> key = Key.get(EntityManager.class);
        EntityManager manager = connection == null ? null : EntityManager.class.cast(connection.get(key));
        if (manager == null) {
            manager = currentManager.get();
        }
        final EntityTransaction tx = manager.getTransaction();
        final boolean localTx = !tx.isActive();
        if (localTx) {
            LOG.trace("Beginning automatic transaction");
            tx.begin();
        } else {
            LOG.trace("Transaction already active");
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (RuntimeException e) {
            LOG.error("Exception inside automatic transaction context", e);
            tx.rollback();
            throw e;
        }

        try {
            if (localTx) {
                tx.commit();
                LOG.trace("Committed automatic transaction");
            }
            return returnValue;
        } catch (PersistenceException e) {
            LOG.error("Commit in automatic transaction context failed", e);
            tx.rollback();
            throw e;
        }
    }

}

package de.cosmocode.palava.jpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;

import de.cosmocode.palava.ipc.IpcConnection;

public final aspect TransactionAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(TransactionAspect.class);

    private Provider<EntityManager> currentManager;
    private Provider<IpcConnection> currentConnection;

    @Inject
    public void setProvider(Provider<EntityManager> manager, Provider<IpcConnection> connection) {
        this.currentManager = Preconditions.checkNotNull(manager, "Manager");
        this.currentConnection = Preconditions.checkNotNull(connection, "Connection");
    }

    pointcut createInjector(): call(Injector Guice.createInjector(..));

    @SuppressAjWarnings("adviceDidNotMatch")
    after() returning (Injector injector): createInjector() {
        LOG.trace("Injecting members on {}", this);
        if (currentManager == null) {
            injector.injectMembers(this);
        } else {
            throw new IllegalStateException("An injector has already been created");
        }
    }

    pointcut transactional(): execution(@Transactional * *.*(..));

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final IpcConnection connection = currentConnection.get();
        if (connection == null) return proceed();
        final Key<EntityManager> key = Key.get(EntityManager.class);
        EntityManager manager = connection.get(key);
        if (manager == null) {
            manager = currentManager.get();
        }
        final EntityTransaction tx = manager.getTransaction();
        final boolean localTx = !tx.isActive();
        if (localTx) {
            LOG.trace("Beginning automatic transaction");
            tx.begin();
        } else {
            LOG.trace("Transaction already active");
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (RuntimeException e) {
            LOG.error("Exception inside automatic transaction context", e);
            tx.rollback();
            throw e;
        }

        try {
            if (localTx) {
                tx.commit();
                LOG.trace("Committed automatic transaction");
            }
            return returnValue;
        } catch (PersistenceException e) {
            LOG.error("Commit in automatic transaction context failed", e);
            tx.rollback();
            throw e;
        }
    }

}


Corrected aspects.

Corrected aspects.

git-svn-id: 4050ee570c0b454ed3c2eee326cdaf8b6ad603bd@39 e65ff1b4-dc2a-11dd-afbb-e3e17473af86

package org.jsuffixarrays;

/**
 * This aspect logs the memory state at entry and exit from methods
 * declared in inheriting aspects. The aspect is a singleton, so is generally
 * not very useful for multi-threaded applications or whenever more than one instance
 * of a given instrumented class is used.
 */
abstract aspect MemoryLogger issingleton()
{
    /**
     * Declare classes to track memory from.
     */
    abstract pointcut tracedClasses();

    /**
     * Override and remove methods for which logging should not occur.
     */
    pointcut excludedMethods() : !execution(* *(..));

    /**
     * Declare methods to track memory in.
     */
    final pointcut tracedMethods() :
        tracedClasses() && execution(* *(..)) && !excludedMethods();

    /**
     *
     */
    before () : tracedClasses() && tracedMethods()
    {
        update();
    }

    /**
     *
     */
    after () returning : tracedMethods()
    {
        update();
    }

    /**
     * Starting amount of memory from which we will begin measurements.
     *
     * @see #reset()
     */
    private static volatile long startingPoint;

    /*
     *
     */
    private static volatile long maxMemoryUsed;

    /*
     *
     */
    private static void update()
    {
        final long now = getUsedMemory();
        if (maxMemoryUsed < now)
        {
            maxMemoryUsed = now;
        }
    }

    /*
     *
     */
    private static long getUsedMemory()
    {
        final Runtime rt = Runtime.getRuntime();
        return rt.totalMemory() - rt.freeMemory();
    }

    /**
     * Reset memory status, preparing for measurement.
     */
    public static void reset()
    {
        // Try to clean the GC. Will not work for parallel GC, but we did our best.
        for (int i = 0; i < 5; i++)
        {
            System.gc();
        }

        startingPoint = getUsedMemory();
        maxMemoryUsed = 0;
    }

    /**
     * Returns the absolute memory peak recorded so far.
     */
    public static long getMemoryPeak()
    {
        return maxMemoryUsed;
    }

    /**
     * Returns the maximum memory difference from the last time
     * since {@link #reset()} was called. This value may be negative
     * with certain GCs and scenarios.
     */
    public static long getMemoryUsed()
    {
        return maxMemoryUsed - startingPoint;
    }
}

/**
 * Track memory in {@link Skew} algorithm.
 */
aspect SkewMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(Skew);
    @Override
    pointcut excludedMethods(): execution(* leq*(..));
}

/**
 * Track memory in {@link NaiveSort} algorithm.
 */
aspect NaiveSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(NaiveSort);
    @Override
    pointcut excludedMethods(): execution(* compare(..));
}

/**
 * Track memory in {@link DivSufSort} algorithm.
 */
aspect DivSufSortMemLogger extends MemoryLogger
{
    /*
     * 3 private methods using stack are excluded,
     * because they use max. 64 * 4 bytes of extra memory for stack.
     */
    @Override
    pointcut tracedClasses(): within(DivSufSort) && !within(org.jsuffixarrays.DivSufSort..*);
    @Override
    pointcut excludedMethods(): execution(private * *(..)) ;
}

/**
 * Track memory in {@link QSufSort} algorithm.
 */
aspect QSUfSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(QSufSort);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link BPR} algorithm.
 */
aspect BPRMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(BPR);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link DeepShallow} algorithm.
 */
aspect DeepShallowMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(DeepShallow);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link SAIS} algorithm.
 */
aspect SaisMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(SAIS) && !within(org.jsuffixarrays.SAIS..*);

    @Override
    pointcut excludedMethods(): execution(private * *(..))
        && !execution(private * org.jsuffixarrays.SAIS.SA_IS(..))
        && !execution(private * org.jsuffixarrays.SAIS.induceSA(..));
}

package org.jsuffixarrays;

/**
 * This aspect logs the memory state at entry and exit from methods
 * declared in inheriting aspects. The aspect is a singleton, so is generally
 * not very useful for multi-threaded applications or whenever more than one instance
 * of a given instrumented class is used.
 */
abstract aspect MemoryLogger issingleton()
{
    /**
     * Declare classes to track memory from.
     */
    abstract pointcut tracedClasses();

    /**
     * Override and remove methods for which logging should not occur.
     */
    pointcut excludedMethods() : !execution(* *(..));

    /**
     * Declare methods to track memory in.
     */
    final pointcut tracedMethods() :
        tracedClasses() && execution(* *(..)) && !excludedMethods();

    /**
     *
     */
    before () : tracedClasses() && tracedMethods()
    {
        update();
    }

    /**
     *
     */
    after () returning : tracedMethods()
    {
        update();
    }

    /**
     * Starting amount of memory from which we will begin measurements.
     *
     * @see #reset()
     */
    private static volatile long startingPoint;

    /*
     *
     */
    private static volatile long maxMemoryUsed;

    /*
     *
     */
    private static void update()
    {
        final long now = getUsedMemory();
        if (maxMemoryUsed < now)
        {
            maxMemoryUsed = now;
        }
    }

    /*
     *
     */
    private static long getUsedMemory()
    {
        final Runtime rt = Runtime.getRuntime();
        return rt.totalMemory() - rt.freeMemory();
    }

    /**
     * Reset memory status, preparing for measurement.
     */
    public static void reset()
    {
        // Try to clean the GC. Will not work for parallel GC, but we did our best.
        for (int i = 0; i < 5; i++)
        {
            System.gc();
        }

        startingPoint = getUsedMemory();
        maxMemoryUsed = 0;
    }

    /**
     * Returns the absolute memory peak recorded so far.
     */
    public static long getMemoryPeak()
    {
        return maxMemoryUsed;
    }

    /**
     * Returns the maximum memory difference from the last time
     * since {@link #reset()} was called. This value may be negative
     * with certain GCs and scenarios.
     */
    public static long getMemoryUsed()
    {
        return maxMemoryUsed - startingPoint;
    }
}

/**
 * Track memory in {@link Skew} algorithm.
 */
aspect SkewMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(Skew);
    @Override
    pointcut excludedMethods(): execution(* leq*(..));
}

/**
 * Track memory in {@link NaiveSort} algorithm.
 */
aspect NaiveSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(NaiveSort);
    @Override
    pointcut excludedMethods(): execution(* compare(..));
}

/**
 * Track memory in {@link DivSufSort} algorithm.
 */
aspect DivSufSortMemLogger extends MemoryLogger
{
    /*
     * 3 private methods using stack are excluded,
     * because they use max. 64 * 4 bytes of extra memory for stack.
     */
    @Override
    pointcut tracedClasses(): within(DivSufSort) && !within(org.jsuffixarrays.DivSufSort..*);
    @Override
    pointcut excludedMethods(): execution(private * *(..)) ;
}

/**
 * Track memory in {@link QSufSort} algorithm.
 */
aspect QSUfSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(QSufSort);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link BPR} algorithm.
 */
aspect BPRMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(BPR);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link DeepShallow} algorithm.
 */
aspect DeepShallowMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(DeepShallow);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link SAIS} algorithm.
 */
aspect SaisMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(SAIS) && !within(org.jsuffixarrays.SAIS..*);

    @Override
    pointcut excludedMethods(): execution(private * *(..))
        && !execution(private * SA_IS(..))
        && !execution(private * induceSA(..));
}


changed logging from trace to debug on actions

/**
 * Copyright 2010 CosmoCode GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.cosmocode.palava.jta;

import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Provider;

import de.cosmocode.palava.core.aop.AbstractPalavaAspect;

public abstract aspect AbstractUserTransactionAspect extends AbstractPalavaAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractUserTransactionAspect.class);

    private Provider<UserTransaction> provider;

    @Inject
    void setProvider(Provider<UserTransaction> provider) {
        this.provider = Preconditions.checkNotNull(provider, "Provider");
    }

    protected abstract pointcut transactional();

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final UserTransaction tx = provider.get();
        LOG.trace("Using transaction {}", tx);

        try {
            LOG.trace("Status of transaction: {}", tx.getStatus());
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        final boolean local;

        try {
            local = tx.getStatus() == Status.STATUS_NO_TRANSACTION;
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        if (local) {
            LOG.trace("Beginning automatic transaction {}", tx);
            try {
                tx.begin();
            } catch (NotSupportedException e) {
                throw new IllegalStateException(e);
            } catch (SystemException e) {
                throw new IllegalStateException(e);
            }
        } else {
            LOG.trace("Transaction {} already active", tx);
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (Exception e) {
            try {
                if (local &&
                    (tx.getStatus() == Status.STATUS_ACTIVE || tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)) {
                    LOG.info("Rolling back local/active transaction {}", tx);
                    tx.rollback();
                } else if (tx.getStatus() != Status.STATUS_ROLLEDBACK || tx.getStatus() != Status.STATUS_ROLLING_BACK) {
                    LOG.debug("Setting transaction {} as rollback only", tx);
                    tx.setRollbackOnly();
                }
            } catch (Exception inner) {
                LOG.error("Rollback failed", inner);
            }
            throw new IllegalStateException(e);
        }

        final int status;

        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        if (local) {
            if (status == Status.STATUS_MARKED_ROLLBACK) {
                try {
                    LOG.debug("Rolling back marked transaction {}", tx);
                    tx.rollback();
                } catch (SystemException e) {
                    throw new IllegalStateException(e);
                }
            } else {
                try {
                    tx.commit();
                    LOG.debug("Committed automatic transaction {}", tx);
                } catch (Exception e) {
                    try {
                        LOG.info("Rolling back transaction {}", tx);
                        tx.rollback();
                    } catch (Exception inner) {
                        LOG.error("Rollback failed", inner);
                    }
                    throw new IllegalStateException(e);
                }
            }
        }

        return returnValue;
    }

}

/**
 * Copyright 2010 CosmoCode GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.cosmocode.palava.jta;

import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Provider;

import de.cosmocode.palava.core.aop.AbstractPalavaAspect;

public abstract aspect AbstractUserTransactionAspect extends AbstractPalavaAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractUserTransactionAspect.class);

    private Provider<UserTransaction> provider;

    @Inject
    void setProvider(Provider<UserTransaction> provider) {
        this.provider = Preconditions.checkNotNull(provider, "Provider");
    }

    protected abstract pointcut transactional();

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final UserTransaction tx = provider.get();
        LOG.trace("Using transaction {}", tx);

        try {
            LOG.trace("Status of transaction: {}", tx.getStatus());
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        final boolean local;

        try {
            local = tx.getStatus() == Status.STATUS_NO_TRANSACTION;
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        if (local) {
            LOG.trace("Beginning automatic transaction {}", tx);
            try {
                tx.begin();
            } catch (NotSupportedException e) {
                throw new IllegalStateException(e);
            } catch (SystemException e) {
                throw new IllegalStateException(e);
            }
        } else {
            LOG.trace("Transaction {} already active", tx);
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (Exception e) {
            try {
                if (local &&
                    (tx.getStatus() == Status.STATUS_ACTIVE || tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)) {
                    LOG.info("Rolling back local/active transaction {}", tx);
                    tx.rollback();
                } else if (tx.getStatus() != Status.STATUS_ROLLEDBACK || tx.getStatus() != Status.STATUS_ROLLING_BACK) {
                    LOG.debug("Setting transaction {} as rollback only", tx);
                    tx.setRollbackOnly();
                }
            } catch (Exception inner) {
                LOG.error("Rollback failed", inner);
            }
            throw new IllegalStateException(e);
        }

        final int status;

        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        if (local) {
            if (status == Status.STATUS_MARKED_ROLLBACK) {
                try {
                    LOG.trace("Rolling back marked transaction {}", tx);
                    tx.rollback();
                } catch (SystemException e) {
                    throw new IllegalStateException(e);
                }
            } else {
                try {
                    tx.commit();
                    LOG.trace("Committed automatic transaction {}", tx);
                } catch (Exception e) {
                    try {
                        LOG.info("Rolling back transaction {}", tx);
                        tx.rollback();
                    } catch (Exception inner) {
                        LOG.error("Rollback failed", inner);
                    }
                    throw new IllegalStateException(e);
                }
            }
        }

        return returnValue;
    }

}


added todo

added todo

/**
 * Copyright 2010 CosmoCode GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.cosmocode.palava.jta;

import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Provider;

import de.cosmocode.palava.core.Registry;
import de.cosmocode.palava.core.aop.AbstractPalavaAspect;

public abstract aspect AbstractUserTransactionAspect extends AbstractPalavaAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractUserTransactionAspect.class);

    private Provider<UserTransaction> provider;

    private TransactionBeginEvent begin;
    private TransactionBeganEvent began;
    private TransactionCommitEvent commit;
    private TransactionCommittedEvent committed;
    private TransactionRollbackEvent rollback;
    private TransactionRolledbackEvent rolledback;

    @Inject
    void setProvider(Provider<UserTransaction> provider) {
        this.provider = Preconditions.checkNotNull(provider, "Provider");
    }

    @Inject
    void setRegistry(Registry registry) {
        Preconditions.checkNotNull(registry, "Registry");
        this.begin = registry.proxy(TransactionBeginEvent.class);
        this.began = registry.proxy(TransactionBeganEvent.class);
        this.commit = registry.proxy(TransactionCommitEvent.class);
        this.committed = registry.proxy(TransactionCommittedEvent.class);
        this.rollback = registry.proxy(TransactionRollbackEvent.class);
        this.rolledback = registry.proxy(TransactionRolledbackEvent.class);
    }

    protected abstract pointcut transactional();

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        Preconditions.checkNotNull(provider, "Provider not injected yet");
        final UserTransaction tx = provider.get();
        LOG.trace("Using transaction {}", tx);

        try {
            LOG.trace("Status of transaction: {}", tx.getStatus());
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        int status;
        final boolean local;
        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        local = status == Status.STATUS_NO_TRANSACTION;

        if (local) {
            LOG.debug("Beginning automatic transaction {}", tx);
            try {
                begin.eventTransactionBegin(tx);
                tx.begin();
                began.eventTransactionBegan(tx);
            } catch (NotSupportedException e) {
                throw new IllegalStateException(e);
            } catch (SystemException e) {
                throw new IllegalStateException(e);
            }
        } else {
            LOG.trace("Transaction {} already active (Status: {})", tx, status);
        }

        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        final Object returnValue;

        try {
            LOG.trace("Status before execution: {}", status);
            returnValue = proceed();
        } catch (Exception e) {
            try {
                if (local &&
                    (tx.getStatus() == Status.STATUS_ACTIVE || tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)) {
                    LOG.info("Rolling back local/active transaction {}", tx);
                    rollback(tx);
                } else if (tx.getStatus() != Status.STATUS_ROLLEDBACK || tx.getStatus() != Status.STATUS_ROLLING_BACK) {
                    LOG.debug("Setting transaction {} as rollback only", tx);
                    tx.setRollbackOnly();
                }
            } catch (Exception inner) {
                LOG.error("Rollback failed", inner);
            }
            // FIXME this effectively shadows the real exceptions thus preventing correct exception handling
            throw new IllegalStateException(e);
        }

        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        LOG.trace("Status after execution: {}", status);

        if (local) {
            if (status == Status.STATUS_MARKED_ROLLBACK) {
                try {
                    LOG.debug("Rolling back marked transaction {}", tx);
                    rollback(tx);
                } catch (SystemException e) {
                    throw new IllegalStateException(e);
                }
            } else {
                try {
                    commit.eventTransactionCommit(tx);
                    tx.commit();
                    committed.eventTransactionCommitted(tx);
                    LOG.debug("Committed automatic transaction {}", tx);
                } catch (Exception e) {
                    try {
                        LOG.info("Rolling back transaction {}", tx);
                        rollback(tx);
                    } catch (Exception inner) {
                        LOG.error("Rollback failed", inner);
                    }
                    throw new IllegalStateException(e);
                }
            }
        }

        return returnValue;
    }

    private void rollback(UserTransaction tx) throws SystemException {
        rollback.eventTransactionRollback(tx);
        tx.rollback();
        rolledback.eventTransactionRolledback(tx);
    }

}

/**
 * Copyright 2010 CosmoCode GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.cosmocode.palava.jta;

import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Provider;

import de.cosmocode.palava.core.Registry;
import de.cosmocode.palava.core.aop.AbstractPalavaAspect;

public abstract aspect AbstractUserTransactionAspect extends AbstractPalavaAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractUserTransactionAspect.class);

    private Provider<UserTransaction> provider;

    private TransactionBeginEvent begin;
    private TransactionBeganEvent began;
    private TransactionCommitEvent commit;
    private TransactionCommittedEvent committed;
    private TransactionRollbackEvent rollback;
    private TransactionRolledbackEvent rolledback;

    @Inject
    void setProvider(Provider<UserTransaction> provider) {
        this.provider = Preconditions.checkNotNull(provider, "Provider");
    }

    @Inject
    void setRegistry(Registry registry) {
        Preconditions.checkNotNull(registry, "Registry");
        this.begin = registry.proxy(TransactionBeginEvent.class);
        this.began = registry.proxy(TransactionBeganEvent.class);
        this.commit = registry.proxy(TransactionCommitEvent.class);
        this.committed = registry.proxy(TransactionCommittedEvent.class);
        this.rollback = registry.proxy(TransactionRollbackEvent.class);
        this.rolledback = registry.proxy(TransactionRolledbackEvent.class);
    }

    protected abstract pointcut transactional();

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        Preconditions.checkNotNull(provider, "Provider not injected yet");
        final UserTransaction tx = provider.get();
        LOG.trace("Using transaction {}", tx);

        try {
            LOG.trace("Status of transaction: {}", tx.getStatus());
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        int status;
        final boolean local;
        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        local = status == Status.STATUS_NO_TRANSACTION;

        if (local) {
            LOG.debug("Beginning automatic transaction {}", tx);
            try {
                begin.eventTransactionBegin(tx);
                tx.begin();
                began.eventTransactionBegan(tx);
            } catch (NotSupportedException e) {
                throw new IllegalStateException(e);
            } catch (SystemException e) {
                throw new IllegalStateException(e);
            }
        } else {
            LOG.trace("Transaction {} already active (Status: {})", tx, status);
        }

        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        final Object returnValue;

        try {
            LOG.trace("Status before execution: {}", status);
            returnValue = proceed();
        } catch (Exception e) {
            try {
                if (local &&
                    (tx.getStatus() == Status.STATUS_ACTIVE || tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)) {
                    LOG.info("Rolling back local/active transaction {}", tx);
                    rollback(tx);
                } else if (tx.getStatus() != Status.STATUS_ROLLEDBACK || tx.getStatus() != Status.STATUS_ROLLING_BACK) {
                    LOG.debug("Setting transaction {} as rollback only", tx);
                    tx.setRollbackOnly();
                }
            } catch (Exception inner) {
                LOG.error("Rollback failed", inner);
            }
            throw new IllegalStateException(e);
        }

        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        LOG.trace("Status after execution: {}", status);

        if (local) {
            if (status == Status.STATUS_MARKED_ROLLBACK) {
                try {
                    LOG.debug("Rolling back marked transaction {}", tx);
                    rollback(tx);
                } catch (SystemException e) {
                    throw new IllegalStateException(e);
                }
            } else {
                try {
                    commit.eventTransactionCommit(tx);
                    tx.commit();
                    committed.eventTransactionCommitted(tx);
                    LOG.debug("Committed automatic transaction {}", tx);
                } catch (Exception e) {
                    try {
                        LOG.info("Rolling back transaction {}", tx);
                        rollback(tx);
                    } catch (Exception inner) {
                        LOG.error("Rollback failed", inner);
                    }
                    throw new IllegalStateException(e);
                }
            }
        }

        return returnValue;
    }

    private void rollback(UserTransaction tx) throws SystemException {
        rollback.eventTransactionRollback(tx);
        tx.rollback();
        rolledback.eventTransactionRolledback(tx);
    }

}