//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2019.02.25 at 12:05:09 AM CET
//

package com.hack23.cia.model.internal.application.data.committee.impl;

import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.hack23.cia.model.common.api.ModelObject;
import com.hack23.cia.model.common.impl.xml.XmlDateTypeAdapter;

/**
 *
Java class for ViewRiksdagenCommitteeBallotDecisionPartySummary complex type.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *
 *

 * <complexType name="ViewRiksdagenCommitteeBallotDecisionPartySummary">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="embeddedId" type="{http://committee.data.application.internal.model.cia.hack23.com/impl}ViewRiksdagenCommitteeBallotDecisionPartyEmbeddedId"/>
 *         <element name="committee_report" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="rm" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="title" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="sub_title" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="end_number" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="org" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="created_date" type="{http://www.w3.org/2001/XMLSchema}date"/>
 *         <element name="public_date" type="{http://www.w3.org/2001/XMLSchema}date"/>
 *         <element name="ballot_id" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="decision_type" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="against_proposal_parties" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="against_proposal_number" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="winner" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="ballot_type" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="label" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="vote_date" type="{http://www.w3.org/2001/XMLSchema}date"/>
 *         <element name="avg_born_year" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="total_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="yes_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="no_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="abstain_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="absent_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="approved" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
 *         <element name="no_winner" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
 *         <element name="percentage_yes" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="percentage_no" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="percentage_absent" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="percentage_abstain" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="percentage_male" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="party_avg_born_year" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="party_total_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="party_yes_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="party_no_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="party_abstain_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="party_absent_votes" type="{http://www.w3.org/2001/XMLSchema}long"/>
 *         <element name="party_approved" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
 *         <element name="party_no_winner" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
 *         <element name="party_percentage_yes" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="party_percentage_no" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="party_percentage_absent" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="party_percentage_abstain" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *         <element name="party_percentage_male" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 *

 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ViewRiksdagenCommitteeBallotDecisionPartySummary", propOrder = {
    "embeddedId",
    "committeeReport",
    "rm",
    "title",
    "subTitle",
    "endNumber",
    "org",
    "createdDate",
    "publicDate",
    "ballotId",
    "decisionType",
    "againstProposalParties",
    "againstProposalNumber",
    "winner",
    "ballotType",
    "label",
    "voteDate",
    "avgBornYear",
    "totalVotes",
    "yesVotes",
    "noVotes",
    "abstainVotes",
    "absentVotes",
    "approved",
    "noWinner",
    "percentageYes",
    "percentageNo",
    "percentageAbsent",
    "percentageAbstain",
    "percentageMale",
    "partyAvgBornYear",
    "partyTotalVotes",
    "partyYesVotes",
    "partyNoVotes",
    "partyAbstainVotes",
    "partyAbsentVotes",
    "partyApproved",
    "partyNoWinner",
    "partyPercentageYes",
    "partyPercentageNo",
    "partyPercentageAbsent",
    "partyPercentageAbstain",
    "partyPercentageMale"
})
@Entity(name = "ViewRiksdagenCommitteeBallotDecisionPartySummary")
@Table(name = "View_Riksdagen_Committee_Ballot_Decision_Party_Summary")
@Inheritance(strategy = InheritanceType.JOINED)
public class ViewRiksdagenCommitteeBallotDecisionPartySummary
    implements ModelObject
{

    /**
	 *
	 */
	private static final long serialVersionUID = 1L;
	@XmlElement(required = true)
    protected ViewRiksdagenCommitteeBallotDecisionPartyEmbeddedId embeddedId;
    @XmlElement(name = "committee_report", required = true)
    protected String committeeReport;
    @XmlElement(required = true)
    protected String rm;
    @XmlElement(required = true)
    protected String title;
    @XmlElement(name = "sub_title", required = true)
    protected String subTitle;
    @XmlElement(name = "end_number", required = true)
    protected BigDecimal endNumber;
    @XmlElement(required = true)
    protected String org;
    @XmlElement(name = "created_date", required = true, type = String.class)
    @XmlJavaTypeAdapter(XmlDateTypeAdapter.class)
    @XmlSchemaType(name = "date")
    protected Date createdDate;
    @XmlElement(name = "public_date", required = true, type = String.class)
    @XmlJavaTypeAdapter(XmlDateTypeAdapter.class)
    @XmlSchemaType(name = "date")
    protected Date publicDate;
    @XmlElement(name = "ballot_id", required = true)
    protected String ballotId;
    @XmlElement(name = "decision_type", required = true)
    protected String decisionType;
    @XmlElement(name = "against_proposal_parties", required = true)
    protected String againstProposalParties;
    @XmlElement(name = "against_proposal_number", required = true)
    protected BigDecimal againstProposalNumber;
    @XmlElement(required = true)
    protected String winner;
    @XmlElement(name = "ballot_type", required = true)
    protected String ballotType;
    @XmlElement(required = true)
    protected String label;
    @XmlElement(name = "vote_date", required = true, type = String.class)
    @XmlJavaTypeAdapter(XmlDateTypeAdapter.class)
    @XmlSchemaType(name = "date")
    protected Date voteDate;
    @XmlElement(name = "avg_born_year", required = true)
    protected BigDecimal avgBornYear;
    @XmlElement(name = "total_votes")
    protected long totalVotes;
    @XmlElement(name = "yes_votes")
    protected long yesVotes;
    @XmlElement(name = "no_votes")
    protected long noVotes;
    @XmlElement(name = "abstain_votes")
    protected long abstainVotes;
    @XmlElement(name = "absent_votes")
    protected long absentVotes;
    protected boolean approved;
    @XmlElement(name = "no_winner")
    protected boolean noWinner;
    @XmlElement(name = "percentage_yes", required = true)
    protected BigDecimal percentageYes;
    @XmlElement(name = "percentage_no", required = true)
    protected BigDecimal percentageNo;
    @XmlElement(name = "percentage_absent", required = true)
    protected BigDecimal percentageAbsent;
    @XmlElement(name = "percentage_abstain", required = true)
    protected BigDecimal percentageAbstain;
    @XmlElement(name = "percentage_male", required = true)
    protected BigDecimal percentageMale;
    @XmlElement(name = "party_avg_born_year", required = true)
    protected BigDecimal partyAvgBornYear;
    @XmlElement(name = "party_total_votes")
    protected long partyTotalVotes;
    @XmlElement(name = "party_yes_votes")
    protected long partyYesVotes;
    @XmlElement(name = "party_no_votes")
    protected long partyNoVotes;
    @XmlElement(name = "party_abstain_votes")
    protected long partyAbstainVotes;
    @XmlElement(name = "party_absent_votes")
    protected long partyAbsentVotes;
    @XmlElement(name = "party_approved")
    protected boolean partyApproved;
    @XmlElement(name = "party_no_winner")
    protected boolean partyNoWinner;
    @XmlElement(name = "party_percentage_yes", required = true)
    protected BigDecimal partyPercentageYes;
    @XmlElement(name = "party_percentage_no", required = true)
    protected BigDecimal partyPercentageNo;
    @XmlElement(name = "party_percentage_absent", required = true)
    protected BigDecimal partyPercentageAbsent;
    @XmlElement(name = "party_percentage_abstain", required = true)
    protected BigDecimal partyPercentageAbstain;
    @XmlElement(name = "party_percentage_male", required = true)
    protected BigDecimal partyPercentageMale;

    /**
     * Gets the value of the embeddedId property.
     *
     * @return
     *     possible object is
     *     {@link ViewRiksdagenCommitteeBallotDecisionPartyEmbeddedId }
     *
     */
    @EmbeddedId
    @AttributeOverrides({
        @AttributeOverride(name = "id", column = @Column(name = "EMBEDDED_ID_ID")),
        @AttributeOverride(name = "party", column = @Column(name = "EMBEDDED_ID_PARTY")),
        @AttributeOverride(name = "hangarId", column = @Column(name = "EMBEDDED_ID_HANGAR_ID", precision = 20, scale = 10)),
        @AttributeOverride(name = "issue", column = @Column(name = "EMBEDDED_ID_ISSUE")),
        @AttributeOverride(name = "concern", column = @Column(name = "EMBEDDED_ID_CONCERN"))
    })
    public ViewRiksdagenCommitteeBallotDecisionPartyEmbeddedId getEmbeddedId() {
        return embeddedId;
    }

    /**
     * Sets the value of the embeddedId property.
     *
     * @param value
     *     allowed object is
     *     {@link ViewRiksdagenCommitteeBallotDecisionPartyEmbeddedId }
     *
     */
    public void setEmbeddedId(final ViewRiksdagenCommitteeBallotDecisionPartyEmbeddedId value) {
        this.embeddedId = value;
    }

    /**
     * Gets the value of the committeeReport property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "COMMITTEE_REPORT")
    public String getCommitteeReport() {
        return committeeReport;
    }

    /**
     * Sets the value of the committeeReport property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setCommitteeReport(final String value) {
        this.committeeReport = value;
    }

    /**
     * Gets the value of the rm property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "RM")
    public String getRm() {
        return rm;
    }

    /**
     * Sets the value of the rm property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setRm(final String value) {
        this.rm = value;
    }

    /**
     * Gets the value of the title property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "TITLE")
    public String getTitle() {
        return title;
    }

    /**
     * Sets the value of the title property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTitle(final String value) {
        this.title = value;
    }

    /**
     * Gets the value of the subTitle property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "SUB_TITLE")
    public String getSubTitle() {
        return subTitle;
    }

    /**
     * Sets the value of the subTitle property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setSubTitle(final String value) {
        this.subTitle = value;
    }

    /**
     * Gets the value of the endNumber property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "END_NUMBER", precision = 20, scale = 10)
    public BigDecimal getEndNumber() {
        return endNumber;
    }

    /**
     * Sets the value of the endNumber property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setEndNumber(final BigDecimal value) {
        this.endNumber = value;
    }

    /**
     * Gets the value of the org property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "ORG")
    public String getOrg() {
        return org;
    }

    /**
     * Sets the value of the org property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setOrg(final String value) {
        this.org = value;
    }

    /**
     * Gets the value of the createdDate property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "CREATED_DATE")
    @Temporal(TemporalType.DATE)
    public Date getCreatedDate() {
        return createdDate;
    }

    /**
     * Sets the value of the createdDate property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setCreatedDate(final Date value) {
        this.createdDate = value;
    }

    /**
     * Gets the value of the publicDate property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "PUBLIC_DATE")
    @Temporal(TemporalType.DATE)
    public Date getPublicDate() {
        return publicDate;
    }

    /**
     * Sets the value of the publicDate property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setPublicDate(final Date value) {
        this.publicDate = value;
    }

    /**
     * Gets the value of the ballotId property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "BALLOT_ID")
    public String getBallotId() {
        return ballotId;
    }

    /**
     * Sets the value of the ballotId property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setBallotId(final String value) {
        this.ballotId = value;
    }

    /**
     * Gets the value of the decisionType property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "DECISION_TYPE")
    public String getDecisionType() {
        return decisionType;
    }

    /**
     * Sets the value of the decisionType property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setDecisionType(final String value) {
        this.decisionType = value;
    }

    /**
     * Gets the value of the againstProposalParties property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "AGAINST_PROPOSAL_PARTIES")
    public String getAgainstProposalParties() {
        return againstProposalParties;
    }

    /**
     * Sets the value of the againstProposalParties property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setAgainstProposalParties(final String value) {
        this.againstProposalParties = value;
    }

    /**
     * Gets the value of the againstProposalNumber property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "AGAINST_PROPOSAL_NUMBER", precision = 20, scale = 10)
    public BigDecimal getAgainstProposalNumber() {
        return againstProposalNumber;
    }

    /**
     * Sets the value of the againstProposalNumber property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setAgainstProposalNumber(final BigDecimal value) {
        this.againstProposalNumber = value;
    }

    /**
     * Gets the value of the winner property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "WINNER")
    public String getWinner() {
        return winner;
    }

    /**
     * Sets the value of the winner property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setWinner(final String value) {
        this.winner = value;
    }

    /**
     * Gets the value of the ballotType property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "BALLOT_TYPE")
    public String getBallotType() {
        return ballotType;
    }

    /**
     * Sets the value of the ballotType property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setBallotType(final String value) {
        this.ballotType = value;
    }

    /**
     * Gets the value of the label property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "LABEL")
    public String getLabel() {
        return label;
    }

    /**
     * Sets the value of the label property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setLabel(final String value) {
        this.label = value;
    }

    /**
     * Gets the value of the voteDate property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Basic
    @Column(name = "VOTE_DATE")
    @Temporal(TemporalType.DATE)
    public Date getVoteDate() {
        return voteDate;
    }

    /**
     * Sets the value of the voteDate property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setVoteDate(final Date value) {
        this.voteDate = value;
    }

    /**
     * Gets the value of the avgBornYear property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "AVG_BORN_YEAR", precision = 20, scale = 10)
    public BigDecimal getAvgBornYear() {
        return avgBornYear;
    }

    /**
     * Sets the value of the avgBornYear property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setAvgBornYear(final BigDecimal value) {
        this.avgBornYear = value;
    }

    /**
     * Gets the value of the totalVotes property.
     *
     */
    @Basic
    @Column(name = "TOTAL_VOTES", precision = 20)
    public long getTotalVotes() {
        return totalVotes;
    }

    /**
     * Sets the value of the totalVotes property.
     *
     */
    public void setTotalVotes(final long value) {
        this.totalVotes = value;
    }

    /**
     * Gets the value of the yesVotes property.
     *
     */
    @Basic
    @Column(name = "YES_VOTES", precision = 20)
    public long getYesVotes() {
        return yesVotes;
    }

    /**
     * Sets the value of the yesVotes property.
     *
     */
    public void setYesVotes(final long value) {
        this.yesVotes = value;
    }

    /**
     * Gets the value of the noVotes property.
     *
     */
    @Basic
    @Column(name = "NO_VOTES", precision = 20)
    public long getNoVotes() {
        return noVotes;
    }

    /**
     * Sets the value of the noVotes property.
     *
     */
    public void setNoVotes(final long value) {
        this.noVotes = value;
    }

    /**
     * Gets the value of the abstainVotes property.
     *
     */
    @Basic
    @Column(name = "ABSTAIN_VOTES", precision = 20)
    public long getAbstainVotes() {
        return abstainVotes;
    }

    /**
     * Sets the value of the abstainVotes property.
     *
     */
    public void setAbstainVotes(final long value) {
        this.abstainVotes = value;
    }

    /**
     * Gets the value of the absentVotes property.
     *
     */
    @Basic
    @Column(name = "ABSENT_VOTES", precision = 20)
    public long getAbsentVotes() {
        return absentVotes;
    }

    /**
     * Sets the value of the absentVotes property.
     *
     */
    public void setAbsentVotes(final long value) {
        this.absentVotes = value;
    }

    /**
     * Gets the value of the approved property.
     *
     */
    @Basic
    @Column(name = "APPROVED")
    public boolean isApproved() {
        return approved;
    }

    /**
     * Sets the value of the approved property.
     *
     */
    public void setApproved(final boolean value) {
        this.approved = value;
    }

    /**
     * Gets the value of the noWinner property.
     *
     */
    @Basic
    @Column(name = "NO_WINNER")
    public boolean isNoWinner() {
        return noWinner;
    }

    /**
     * Sets the value of the noWinner property.
     *
     */
    public void setNoWinner(final boolean value) {
        this.noWinner = value;
    }

    /**
     * Gets the value of the percentageYes property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PERCENTAGE_YES", precision = 20, scale = 10)
    public BigDecimal getPercentageYes() {
        return percentageYes;
    }

    /**
     * Sets the value of the percentageYes property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPercentageYes(final BigDecimal value) {
        this.percentageYes = value;
    }

    /**
     * Gets the value of the percentageNo property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PERCENTAGE_NO", precision = 20, scale = 10)
    public BigDecimal getPercentageNo() {
        return percentageNo;
    }

    /**
     * Sets the value of the percentageNo property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPercentageNo(final BigDecimal value) {
        this.percentageNo = value;
    }

    /**
     * Gets the value of the percentageAbsent property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PERCENTAGE_ABSENT", precision = 20, scale = 10)
    public BigDecimal getPercentageAbsent() {
        return percentageAbsent;
    }

    /**
     * Sets the value of the percentageAbsent property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPercentageAbsent(final BigDecimal value) {
        this.percentageAbsent = value;
    }

    /**
     * Gets the value of the percentageAbstain property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PERCENTAGE_ABSTAIN", precision = 20, scale = 10)
    public BigDecimal getPercentageAbstain() {
        return percentageAbstain;
    }

    /**
     * Sets the value of the percentageAbstain property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPercentageAbstain(final BigDecimal value) {
        this.percentageAbstain = value;
    }

    /**
     * Gets the value of the percentageMale property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PERCENTAGE_MALE", precision = 20, scale = 10)
    public BigDecimal getPercentageMale() {
        return percentageMale;
    }

    /**
     * Sets the value of the percentageMale property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPercentageMale(final BigDecimal value) {
        this.percentageMale = value;
    }

    /**
     * Gets the value of the partyAvgBornYear property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PARTY_AVG_BORN_YEAR", precision = 20, scale = 10)
    public BigDecimal getPartyAvgBornYear() {
        return partyAvgBornYear;
    }

    /**
     * Sets the value of the partyAvgBornYear property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPartyAvgBornYear(final BigDecimal value) {
        this.partyAvgBornYear = value;
    }

    /**
     * Gets the value of the partyTotalVotes property.
     *
     */
    @Basic
    @Column(name = "PARTY_TOTAL_VOTES", precision = 20)
    public long getPartyTotalVotes() {
        return partyTotalVotes;
    }

    /**
     * Sets the value of the partyTotalVotes property.
     *
     */
    public void setPartyTotalVotes(final long value) {
        this.partyTotalVotes = value;
    }

    /**
     * Gets the value of the partyYesVotes property.
     *
     */
    @Basic
    @Column(name = "PARTY_YES_VOTES", precision = 20)
    public long getPartyYesVotes() {
        return partyYesVotes;
    }

    /**
     * Sets the value of the partyYesVotes property.
     *
     */
    public void setPartyYesVotes(final long value) {
        this.partyYesVotes = value;
    }

    /**
     * Gets the value of the partyNoVotes property.
     *
     */
    @Basic
    @Column(name = "PARTY_NO_VOTES", precision = 20)
    public long getPartyNoVotes() {
        return partyNoVotes;
    }

    /**
     * Sets the value of the partyNoVotes property.
     *
     */
    public void setPartyNoVotes(final long value) {
        this.partyNoVotes = value;
    }

    /**
     * Gets the value of the partyAbstainVotes property.
     *
     */
    @Basic
    @Column(name = "PARTY_ABSTAIN_VOTES", precision = 20)
    public long getPartyAbstainVotes() {
        return partyAbstainVotes;
    }

    /**
     * Sets the value of the partyAbstainVotes property.
     *
     */
    public void setPartyAbstainVotes(final long value) {
        this.partyAbstainVotes = value;
    }

    /**
     * Gets the value of the partyAbsentVotes property.
     *
     */
    @Basic
    @Column(name = "PARTY_ABSENT_VOTES", precision = 20)
    public long getPartyAbsentVotes() {
        return partyAbsentVotes;
    }

    /**
     * Sets the value of the partyAbsentVotes property.
     *
     */
    public void setPartyAbsentVotes(final long value) {
        this.partyAbsentVotes = value;
    }

    /**
     * Gets the value of the partyApproved property.
     *
     */
    @Basic
    @Column(name = "PARTY_APPROVED")
    public boolean isPartyApproved() {
        return partyApproved;
    }

    /**
     * Sets the value of the partyApproved property.
     *
     */
    public void setPartyApproved(final boolean value) {
        this.partyApproved = value;
    }

    /**
     * Gets the value of the partyNoWinner property.
     *
     */
    @Basic
    @Column(name = "PARTY_NO_WINNER")
    public boolean isPartyNoWinner() {
        return partyNoWinner;
    }

    /**
     * Sets the value of the partyNoWinner property.
     *
     */
    public void setPartyNoWinner(final boolean value) {
        this.partyNoWinner = value;
    }

    /**
     * Gets the value of the partyPercentageYes property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PARTY_PERCENTAGE_YES", precision = 20, scale = 10)
    public BigDecimal getPartyPercentageYes() {
        return partyPercentageYes;
    }

    /**
     * Sets the value of the partyPercentageYes property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPartyPercentageYes(final BigDecimal value) {
        this.partyPercentageYes = value;
    }

    /**
     * Gets the value of the partyPercentageNo property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PARTY_PERCENTAGE_NO", precision = 20, scale = 10)
    public BigDecimal getPartyPercentageNo() {
        return partyPercentageNo;
    }

    /**
     * Sets the value of the partyPercentageNo property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPartyPercentageNo(final BigDecimal value) {
        this.partyPercentageNo = value;
    }

    /**
     * Gets the value of the partyPercentageAbsent property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PARTY_PERCENTAGE_ABSENT", precision = 20, scale = 10)
    public BigDecimal getPartyPercentageAbsent() {
        return partyPercentageAbsent;
    }

    /**
     * Sets the value of the partyPercentageAbsent property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPartyPercentageAbsent(final BigDecimal value) {
        this.partyPercentageAbsent = value;
    }

    /**
     * Gets the value of the partyPercentageAbstain property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PARTY_PERCENTAGE_ABSTAIN", precision = 20, scale = 10)
    public BigDecimal getPartyPercentageAbstain() {
        return partyPercentageAbstain;
    }

    /**
     * Sets the value of the partyPercentageAbstain property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPartyPercentageAbstain(final BigDecimal value) {
        this.partyPercentageAbstain = value;
    }

    /**
     * Gets the value of the partyPercentageMale property.
     *
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *
     */
    @Basic
    @Column(name = "PARTY_PERCENTAGE_MALE", precision = 20, scale = 10)
    public BigDecimal getPartyPercentageMale() {
        return partyPercentageMale;
    }

    /**
     * Sets the value of the partyPercentageMale property.
     *
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *
     */
    public void setPartyPercentageMale(final BigDecimal value) {
        this.partyPercentageMale = value;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withEmbeddedId(final ViewRiksdagenCommitteeBallotDecisionPartyEmbeddedId value) {
        setEmbeddedId(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withCommitteeReport(final String value) {
        setCommitteeReport(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withRm(final String value) {
        setRm(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withTitle(final String value) {
        setTitle(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withSubTitle(final String value) {
        setSubTitle(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withEndNumber(final BigDecimal value) {
        setEndNumber(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withOrg(final String value) {
        setOrg(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withCreatedDate(final Date value) {
        setCreatedDate(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPublicDate(final Date value) {
        setPublicDate(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withBallotId(final String value) {
        setBallotId(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withDecisionType(final String value) {
        setDecisionType(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withAgainstProposalParties(final String value) {
        setAgainstProposalParties(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withAgainstProposalNumber(final BigDecimal value) {
        setAgainstProposalNumber(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withWinner(final String value) {
        setWinner(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withBallotType(final String value) {
        setBallotType(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withLabel(final String value) {
        setLabel(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withVoteDate(final Date value) {
        setVoteDate(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withAvgBornYear(final BigDecimal value) {
        setAvgBornYear(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withTotalVotes(final long value) {
        setTotalVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withYesVotes(final long value) {
        setYesVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withNoVotes(final long value) {
        setNoVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withAbstainVotes(final long value) {
        setAbstainVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withAbsentVotes(final long value) {
        setAbsentVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withApproved(final boolean value) {
        setApproved(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withNoWinner(final boolean value) {
        setNoWinner(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPercentageYes(final BigDecimal value) {
        setPercentageYes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPercentageNo(final BigDecimal value) {
        setPercentageNo(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPercentageAbsent(final BigDecimal value) {
        setPercentageAbsent(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPercentageAbstain(final BigDecimal value) {
        setPercentageAbstain(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPercentageMale(final BigDecimal value) {
        setPercentageMale(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyAvgBornYear(final BigDecimal value) {
        setPartyAvgBornYear(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyTotalVotes(final long value) {
        setPartyTotalVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyYesVotes(final long value) {
        setPartyYesVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyNoVotes(final long value) {
        setPartyNoVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyAbstainVotes(final long value) {
        setPartyAbstainVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyAbsentVotes(final long value) {
        setPartyAbsentVotes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyApproved(final boolean value) {
        setPartyApproved(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyNoWinner(final boolean value) {
        setPartyNoWinner(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyPercentageYes(final BigDecimal value) {
        setPartyPercentageYes(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyPercentageNo(final BigDecimal value) {
        setPartyPercentageNo(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyPercentageAbsent(final BigDecimal value) {
        setPartyPercentageAbsent(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyPercentageAbstain(final BigDecimal value) {
        setPartyPercentageAbstain(value);
        return this;
    }

    public ViewRiksdagenCommitteeBallotDecisionPartySummary withPartyPercentageMale(final BigDecimal value) {
        setPartyPercentageMale(value);
        return this;
    }

	@Override
	public final String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}

	@Override
	public final boolean equals(final Object obj) {
		return EqualsBuilder.reflectionEquals(this, obj);
	}

	@Override
	public final int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this);
	}

}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.service.data.impl;

import java.io.Serializable;
import java.util.List;
import java.util.function.Function;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaBuilder.In;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SingularAttribute;

import org.hibernate.CacheMode;
import org.hibernate.search.engine.search.dsl.predicate.SearchPredicateFactoryContext;
import org.hibernate.search.engine.search.dsl.predicate.SearchPredicateTerminalContext;
import org.hibernate.search.engine.search.dsl.query.SearchQueryContext;
import org.hibernate.search.mapper.orm.Search;
import org.hibernate.search.mapper.orm.search.dsl.query.SearchQueryResultDefinitionContext;
import org.hibernate.search.mapper.orm.search.query.SearchQuery;
import org.javers.spring.annotation.JaversAuditable;
import org.hibernate.search.mapper.orm.session.SearchSession;

import com.hack23.cia.service.data.api.AbstractGenericDAO;
import com.hack23.cia.service.data.impl.util.LoadHelper;

/**
 * The Class AbstractGenericDAOImpl.
 *
 * @param <T>
 *            the generic type
 * @param <I>
 *            the generic type
 */

abstract class AbstractGenericDAOImpl<T extends Serializable, I extends Serializable>
		implements AbstractGenericDAO<T, I> {

	/** The entity manager. */
	@PersistenceContext(name = "ciaPersistenceUnit")
	private EntityManager entityManager;

	/** The criteria builder. */
	private CriteriaBuilder criteriaBuilder;

	/** The metamodel. */
	private Metamodel metamodel;

	/** The persistent class. */
	private final Class<T> persistentClass;

	/**
	 * Instantiates a new abstract generic dao impl.
	 *
	 * @param persistentClass
	 *            the persistent class
	 */
	protected AbstractGenericDAOImpl(final Class<T> persistentClass) {
		this.persistentClass = persistentClass;
	}

	/**
	 * Adds the cache hints.
	 *
	 * @param typedQuery
	 *            the typed query
	 * @param comment
	 *            the comment
	 */
	protected final void addCacheHints(final TypedQuery<?> typedQuery, final String comment) {
		typedQuery.setHint("org.hibernate.cacheMode", CacheMode.NORMAL);
		typedQuery.setHint("org.hibernate.cacheable", Boolean.TRUE);
		typedQuery.setHint("org.hibernate.comment", comment);
	}

	/**
	 * Gets the string id list.
	 *
	 * @param property
	 *            the property
	 * @return the string id list
	 */
	protected final List<String> getStringIdList(final SingularAttribute<T, String> property) {
		final CriteriaQuery<String> criteria = getCriteriaBuilder().createQuery(String.class);
		final Root<T> root = criteria.from(persistentClass);
		criteria.select(getCriteriaBuilder().construct(String.class,root.get(property)));
		return getEntityManager().createQuery(criteria).getResultList();
	}

	@Override
	@JaversAuditable
	public final void delete(final T entity) {
		getEntityManager().remove(entity);

	}

	@Override
	public final T findFirstByProperty(final SingularAttribute<T, ? extends Object> property, final Object value) {
		final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
		final Root<T> root = criteriaQuery.from(getPersistentClass());
		criteriaQuery.select(root);
		final Predicate condition = criteriaBuilder.equal(root.get(property), value);
		criteriaQuery.where(condition);
		final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
		addCacheHints(typedQuery, "findFirstByProperty");

		final List<T> resultList = typedQuery.getResultList();

		if (resultList.isEmpty()) {
			return null;
		} else {
			return LoadHelper.recursiveInitialize(resultList.get(0));
		}
	}

	@Override
	public final List<T> findListByProperty(final Object[] values,
			final SingularAttribute<T, ? extends Object>... properties) {
		final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(persistentClass);
		final Root<T> root = criteriaQuery.from(persistentClass);
		criteriaQuery.select(root);

		final Object value = values[0];
		final SingularAttribute<T, ? extends Object> property = properties[0];
		Predicate condition;

		condition = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root, value, property);

		if (values.length > 1) {
			for (int i = 1; i < properties.length; i++) {
				final SingularAttribute<T, ? extends Object> property2 = properties[i];
				final Object value2 = values[i];
				final Predicate condition2 = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root,
						value2, property2);

				condition = criteriaBuilder.and(condition, condition2);
			}
		}

		criteriaQuery.where(condition);

		final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
		addCacheHints(typedQuery, "findListByProperty");

		return typedQuery.getResultList();
	}

	@Override
	public final List<T> findListByProperty(final SingularAttribute<T, ? extends Object> property, final Object value) {
		final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
		final Root<T> root = criteriaQuery.from(getPersistentClass());
		criteriaQuery.select(root);
		final Predicate condition = criteriaBuilder.equal(root.get(property), value);
		criteriaQuery.where(condition);
		final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
		addCacheHints(typedQuery, "findListByProperty");
		return typedQuery.getResultList();
	}

	@Override
	public final List<T> findListByPropertyInList(final SingularAttribute<T, ? extends Object> property, final Object[] values) {
		final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
		final Root<T> root = criteriaQuery.from(getPersistentClass());
		criteriaQuery.select(root);
		final In<Object> in = criteriaBuilder.in((Path<Object>) root.get(property));
		for (final Object object : values) {
			in.value(object);
		}
		criteriaQuery.where(in);
		final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
		addCacheHints(typedQuery, "findListByPropertyInList");
		return typedQuery.getResultList();
	}

	@Override
	public <V> List<T> findListByEmbeddedProperty(final SingularAttribute<T, V> property, final Class<V> clazz2,
			final SingularAttribute<V, ? extends Object> property2, final Object value) {
		return findOrderedByPropertyListByEmbeddedProperty(property,clazz2,property2,value,null);

	}

	@Override
	public <V> List<T> findOrderedByPropertyListByEmbeddedProperty(final SingularAttribute<T, V> property,
			final Class<V> clazz2, final SingularAttribute<V, ? extends Object> property2, final Object value,
			final SingularAttribute<T, ? extends Object> orderByProperty) {
		final CriteriaQuery<T> criteriaQuery = criteriaBuilder
				.createQuery(persistentClass);
		final Root<T> root = criteriaQuery.from(persistentClass);
		criteriaQuery.select(root);

		if (orderByProperty != null) {
			criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderByProperty)));
		}

		final Join<T, V> join = root.join(property);

		final Path<? extends Object> path = join.get(property2);

		final Predicate condition = criteriaBuilder.equal(path, value);

		criteriaQuery.where(condition);

		final TypedQuery<T> typedQuery = entityManager
				.createQuery(criteriaQuery);

		addCacheHints(typedQuery, "findListByEmbeddedProperty." + persistentClass.getSimpleName());

		return typedQuery.getResultList();
	}

	@Override
	public final List<T> getAll() {
		return getAllOrderBy(null);
	}

	@Override
	public final List<T> getAllOrderBy(final SingularAttribute<T, ? extends Object> orderBy) {
		return getPageOrderBy(null, null, orderBy);
	}

	/**
	 * Gets the criteria builder.
	 *
	 * @return the criteria builder
	 */
	public final CriteriaBuilder getCriteriaBuilder() {
		return criteriaBuilder;
	}

	/**
	 * Gets the entity manager.
	 *
	 * @return the entity manager
	 */
	protected final EntityManager getEntityManager() {
		return entityManager;
	}

	/**
	 * Gets the full text entity manager.
	 *
	 * @return the full text entity manager
	 */
	protected final SearchSession getFullTextEntityManager() {
		return Search.getSearchSession(getEntityManager());
	}

	/**
	 * Gets the metamodel.
	 *
	 * @return the metamodel
	 */
	protected final Metamodel getMetamodel() {
		return metamodel;
	}

	@Override
	public final List<T> getPage(final int pageNr, final int resultPerPage) {
		return getPageOrderBy(pageNr, resultPerPage, null);
	}

	@Override
	public final List<T> getPageOrderBy(final int pageNr, final int resultPerPage, final SingularAttribute<T, ? extends Object> orderBy) {
		return getPageOrderBy(Integer.valueOf(pageNr), Integer.valueOf(resultPerPage), orderBy);
	}

	private List<T> getPageOrderBy(final Integer pageNr, final Integer resultPerPage,
			final SingularAttribute<T, ? extends Object> orderBy) {
		final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
		final Root<T> root = criteriaQuery.from(getPersistentClass());

		criteriaQuery.select(root);

		if (orderBy != null) {
			criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderBy)));
		}

		final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
		addCacheHints(typedQuery, "getAll");

		if (pageNr != null && resultPerPage != null) {
			typedQuery.setFirstResult((pageNr - 1) * resultPerPage);
			typedQuery.setMaxResults(resultPerPage);

		}

		return typedQuery.getResultList();

	}

	/**
	 * Gets the persistent class.
	 *
	 * @return the persistent class
	 */
	public final Class<T> getPersistentClass() {
		return this.persistentClass;
	}

	@Override
	public final Long getSize() {
		final CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
		countQuery.select(criteriaBuilder.count(countQuery.from(persistentClass)));
		return getEntityManager().createQuery(countQuery).getSingleResult();
	}

	/**
	 * Inits the.
	 */
	@PostConstruct
	private void init() {
		this.criteriaBuilder = getEntityManager().getCriteriaBuilder();
		this.metamodel = getEntityManager().getMetamodel();
	}

	@Override
	public final T load(final I id) {
		return LoadHelper.recursiveInitialize(getEntityManager().find(getPersistentClass(), id));
	}

	@Override
	@JaversAuditable
	public final T merge(final T entity) {
		return getEntityManager().merge(entity);
	}

	@Override
	@JaversAuditable
	public final void persist(final List<T> list) {
		for (final T t : list) {
			getEntityManager().persist(t);
		}
	}

	@Override
	@JaversAuditable
	public final void persist(final T entity) {
		getEntityManager().persist(entity);
	}

	@Override
	public final List<T> search(final String searchExpression, final Integer maxResults, final String... fields) {
		final SearchQueryResultDefinitionContext<T> queryResult = getFullTextEntityManager().search(persistentClass);
		final SearchQueryContext<? extends SearchQuery<T>> query = queryResult.asEntity()
	        .predicate((Function<? super SearchPredicateFactoryContext, SearchPredicateTerminalContext>) t -> t.match().onFields(fields).matching(searchExpression));
		return query.toQuery().fetch(maxResults).getHits();

	}
}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.service.external.worldbank.impl;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.codec.Charsets;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.http.client.fluent.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.oxm.Unmarshaller;
import org.springframework.stereotype.Component;

import com.hack23.cia.model.external.worldbank.indicators.impl.IndicatorElement;
import com.hack23.cia.model.external.worldbank.indicators.impl.IndicatorsElement;
import com.hack23.cia.service.external.common.api.XmlAgent;
import com.hack23.cia.service.external.common.api.XmlAgentException;
import com.hack23.cia.service.external.worldbank.api.DataFailureException;
import com.hack23.cia.service.external.worldbank.api.WorldBankIndicatorApi;

/**
 * The Class WorldbankIndicatorApiImpl.
 */
@Component
final class WorldbankIndicatorApiImpl extends BaseWorldBankApiImpl implements WorldBankIndicatorApi {

	private static final int IGNORE_TOP_HEADERS_LINE = 4;

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory.getLogger(WorldbankIndicatorApiImpl.class);

	/** The Constant INDICATORS. */
	private static final String INDICATORS = "https://api.worldbank.org/indicators?per_page=5000";

	private static final String PAGE_NUMBER = "&page=";

	/** The Constant PROBLEM_GETTING_WORLDBANK_INDICATOR_LIST. */
	private static final String PROBLEM_GETTING_WORLDBANK_INDICATOR_LIST = "Problem getting worldbank indicator list";

	private static final int SECOND_PAGE = 2;

	/**
	 * The Constant
	 * XMLNS_WB_HTTP_INDICATORS_WORLDBANK_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL.
	 */
	private static final String XMLNS_WB_HTTP_INDICATORS_WORLDBANK_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL = "xmlns:wb=\"http://indicators.worldbank.external.model.cia.hack23.com/impl\"";

	/** The indicators unmarshaller. */
	@Autowired
	@Qualifier("worldbankOrgIndicatorsMarshaller")
	private Unmarshaller indicatorsUnmarshaller;

	/**
	 * Instantiates a new worldbank indicator api impl.
	 */
	@Autowired
	public WorldbankIndicatorApiImpl(final XmlAgent xmlAgent) {
		super(xmlAgent);
	}

	@Override
	public List<IndicatorElement> getIndicators() throws DataFailureException {
		final List<IndicatorElement> result = new ArrayList<>();

		try {
			final IndicatorsElement firstPage = (IndicatorsElement) getXmlAgent().unmarshallXml(indicatorsUnmarshaller,
					INDICATORS, null, XMLNS_WB_HTTP_WWW_WORLDBANK_ORG,
					XMLNS_WB_HTTP_INDICATORS_WORLDBANK_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL);
			result.addAll(firstPage.getIndicator());

			for (int pageNumber = SECOND_PAGE; pageNumber < firstPage.getPages().intValue(); pageNumber++) {
				final IndicatorsElement otherPageResult = (IndicatorsElement) getXmlAgent().unmarshallXml(indicatorsUnmarshaller,
						INDICATORS + PAGE_NUMBER + pageNumber, null, XMLNS_WB_HTTP_WWW_WORLDBANK_ORG,
						XMLNS_WB_HTTP_INDICATORS_WORLDBANK_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL);
				result.addAll(otherPageResult.getIndicator());
			}

		} catch (final XmlAgentException e) {
			LOGGER.warn(PROBLEM_GETTING_WORLDBANK_INDICATOR_LIST);
			throw new DataFailureException(e);
		}

		return result;
	}

	@Override
	public List<String> getIndicatorsWithSwedishData() throws DataFailureException {
		try {
			return Collections.unmodifiableList(readUsingZipInputStream(Request.Get("http://api.worldbank.org/v2/en/country/SWE?downloadformat=csv").execute().returnContent().asStream()));
		} catch (final IOException e) {
			throw new DataFailureException(e);
		}
	}

	/**
	 * Read using zip input stream.
	 *
	 * @param inputStream
	 *            the input stream
	 * @param specificFields
	 *            the specific fields
	 * @return the list
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	private static List<String> readUsingZipInputStream(final InputStream inputStream) throws IOException {
		final BufferedInputStream bis = new BufferedInputStream(inputStream);
		final ZipInputStream is = new ZipInputStream(bis);

		final List<String> list = new ArrayList<>();
		try {
			ZipEntry entry;

			while ((entry = is.getNextEntry()) != null) {
				if (entry.getName().startsWith("API_SWE_")) {
					list.addAll(readCsvContent(is));
				}
			}
		} finally {
			is.close();
		}
		return list;
	}

	/**
	 * Read csv content.
	 *
	 * @param is
	 *            the is
	 * @return the list
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	private static List<String> readCsvContent(final InputStream is) throws IOException {
		final BufferedReader reader = new BufferedReader(new InputStreamReader(is,Charsets.UTF_8));
		for (int i = 0; i < IGNORE_TOP_HEADERS_LINE; i++) {
			final String ignoreFirstLinesWithHeaders = reader.readLine();
		}

		final CSVParser parser = CSVParser.parse(reader, CSVFormat.EXCEL.withHeader().withDelimiter(','));
		final List<CSVRecord> records = parser.getRecords();
		records.remove(0);

		final List<String> list = new ArrayList<>();

		for (final CSVRecord csvRecord : records) {
			list.add(csvRecord.get("Indicator Code"));
		}

		return list;
	}

}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.web.widgets.charts;

import java.util.UUID;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import com.vaadin.annotations.JavaScript;
import com.vaadin.ui.AbstractJavaScriptComponent;

/**
 * The Class SankeyChart.
 */
@JavaScript({ "https://www.gstatic.com/charts/loader.js", "SankeyChart.js" })
public final class SankeyChart extends AbstractJavaScriptComponent {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;

	/** The my id. */
	private String myId;

	/**
	 * Instantiates a new sankey chart.
	 */
	public SankeyChart() {
		myId = "gBarChartComponent" + UUID.randomUUID().toString();
		callFunction("setId", myId);
		setSizeFull();
		setHeight("100%");
		setId(myId);
		getState().myId=myId;
	}

	@Override
	protected SankeyChartState getState() {
		return (SankeyChartState) super.getState();
	}

	/**
	 * Adds the data row.
	 *
	 * @param from
	 *            the from
	 * @param to
	 *            the to
	 * @param weight
	 *            the weight
	 */
	public void addDataRow(final String from, final String to, int weight) {
		getState().addDataRow(from, to, weight);
	}

	/**
	 * Draw chart.
	 */
	public void drawChart() {
		callFunction("doDraw");
	}

	@Override
	public int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this, false);
	}

	@Override
	public boolean equals(Object obj) {
		return EqualsBuilder.reflectionEquals(this, obj);
	}

}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.web.impl.ui.application.views.user.committee.pagemode;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Component;

import com.hack23.cia.model.internal.application.system.impl.ApplicationEventGroup;
import com.hack23.cia.web.impl.ui.application.action.ViewAction;
import com.hack23.cia.web.impl.ui.application.views.common.viewnames.PageMode;
import com.hack23.cia.web.impl.ui.application.views.common.viewnames.UserViews;
import com.vaadin.ui.Layout;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.VerticalLayout;

/**
 * The Class CommitteeRankingOverviewPageModContentFactoryImpl.
 */
@Component
public final class CommitteeRankingOverviewPageModContentFactoryImpl extends AbstractCommitteeRankingPageModContentFactoryImpl {

	/** The Constant NAME. */
	public static final String NAME = UserViews.COMMITTEE_RANKING_VIEW_NAME;

	/** The Constant OVERVIEW. */
	private static final String OVERVIEW = "overview";

	/** The Constant COMMITTEE_RANKING_BY_TOPIC. */
	private static final String COMMITTEE_RANKING_BY_TOPIC = "Committee Ranking by topic";

	/** The Constant COMMITTEE_RANKING_BY_TOPIC_DESCRIPTION. */
	private static final String COMMITTEE_RANKING_BY_TOPIC_DESCRIPTION = "Time served in Committee:ALL:CURRENT:" + "\nPoliticans served in Committee:ALL:CURRENT:"
			+ "\nTop document author NR:ALL:YEAR:CURRENT:*FILTER:DocumnetType"
			+ "\nTop document author SIZE:YEAR:ALL:CURRENT:*FILTER:DocumnetType"

			+ "\nTop decisions NR/PERCENTAGE :ALL:YEAR:CURRENT::#Views:List,Timeline,BarChart,PieChart"
			+ "\nTop Votes NR/PERCENTAGE :ALL:YEAR:CURRENT::#Views:List,Timeline,BarChart,PieChart"

			+ "\nTop vote winner NR/PERCENTAGE :ALL:YEAR:CURRENT::#Views:List,Timeline,BarChart,PieChart"
			+ "\nSearch by name";

	/**
	 * Instantiates a new committee ranking overview page mod content factory
	 * impl.
	 */
	public CommitteeRankingOverviewPageModContentFactoryImpl() {
		super();
	}

	@Override
	public boolean matches(final String page, final String parameters) {
		return NAME.equals(page) && (StringUtils.isEmpty(parameters) || parameters.contains(PageMode.OVERVIEW.toString()));
	}

	@Secured({ "ROLE_ANONYMOUS", "ROLE_USER", "ROLE_ADMIN" })
	@Override
	public Layout createContent(final String parameters, final MenuBar menuBar, final Panel panel) {
		final VerticalLayout panelContent = createPanelContent();

		getCommitteeRankingMenuItemFactory().createCommitteeeRankingMenuBar(menuBar);

		final String pageId = getPageId(parameters);

		panelContent.addComponent(createDescription());

		getCommitteeRankingMenuItemFactory().createOverviewPage(panelContent);

		panel.setCaption(NAME + "::" + OVERVIEW);

		getPageActionEventHelper().createPageEvent(ViewAction.VISIT_COMMITTEE_RANKING_VIEW, ApplicationEventGroup.USER, NAME,
				parameters, pageId);

		return panelContent;

	}

	/**
	 * Creates the description.
	 *
	 * @return the text area
	 */
	private static TextArea createDescription() {
		final TextArea totalCommitteeRankinglistLabel = new TextArea(COMMITTEE_RANKING_BY_TOPIC,
				COMMITTEE_RANKING_BY_TOPIC_DESCRIPTION);
		totalCommitteeRankinglistLabel.setSizeFull();
		totalCommitteeRankinglistLabel.setStyleName("Level2Header");
		return totalCommitteeRankinglistLabel;
	}

}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.web.impl.ui.application.views.common.paging;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.hack23.cia.web.impl.ui.application.views.common.pagelinks.api.PageLinkFactory;
import com.hack23.cia.web.impl.ui.application.views.common.sizing.ContentRatio;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;

/**
 * The Class PagingUtil.
 */
@Component
public final class PagingUtilImpl implements PagingUtil {

	/** The limit for displaying start end links. */
	private static final int LIMIT_FOR_DISPLAYING_START_END_LINKS = 5;

	/** The page one. */
	private static final int PAGE_ONE = 1;

	/** The page separator. */
	private static final char PAGE_SEPARATOR = '/';

	/** The show. */
	private static final String SHOW = " :: Show ";

	/** The results per page. */
	private static final String RESULTS_PER_PAGE = " results per page:";

	/** The pages total results. */
	private static final String PAGES_TOTAL_RESULTS = " pages. Total results:";

	/** The page header. */
	private static final String PAGE_HEADER = "Page: ";

	/** The next page. */
	private static final String NEXT_PAGE = "next page";

	/** The first page. */
	private static final String FIRST_PAGE = "first page";

	/** The last page. */
	private static final String LAST_PAGE = "last page";

	/** The previous page. */
	private static final String PREVIOUS_PAGE = "previous page";

	/** The page link factory. */
	@Autowired
	private PageLinkFactory pageLinkFactory;

	/**
	 * Creates the paging controls.
	 *
	 * @param content       the content
	 * @param name          the name
	 * @param pageId        the page id
	 * @param size          the size
	 * @param pageNr        the page nr
	 * @param resultPerPage the result per page
	 */
	@Override
	public void createPagingControls(final AbstractOrderedLayout content, final String name, final String pageId, final Long size, final int pageNr,
			final int resultPerPage) {
				final HorizontalLayout pagingControls = new HorizontalLayout();
				pagingControls.setSpacing(true);
				pagingControls.setMargin(true);

				final long maxPages = (size +resultPerPage-1) / resultPerPage;

				final StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.append(PAGE_HEADER)
				.append(pageNr)
				.append(PAGE_SEPARATOR)
				.append(maxPages)
				.append(PAGES_TOTAL_RESULTS)
				.append(size)
				.append(RESULTS_PER_PAGE)
				.append(resultPerPage)
				.append(SHOW);
				final Label pageInfo = new Label(stringBuilder.toString());
				pagingControls.addComponent(pageInfo);
				pagingControls.setExpandRatio(pageInfo, ContentRatio.SMALL);

				if (pageNr > PAGE_ONE) {
					addPagingLink(PREVIOUS_PAGE,name, pageId, pageNr -1L,pagingControls);
				}

				if (maxPages > PAGE_ONE && pageNr < maxPages) {
					addPagingLink(NEXT_PAGE,name, pageId, pageNr +1L,pagingControls);
				}

				if (maxPages > LIMIT_FOR_DISPLAYING_START_END_LINKS && pageNr > PAGE_ONE) {
					addPagingLink(FIRST_PAGE,name, pageId, 1,pagingControls);
				}

				if (maxPages > LIMIT_FOR_DISPLAYING_START_END_LINKS && pageNr < maxPages) {
					addPagingLink(LAST_PAGE,name, pageId, maxPages,pagingControls);
				}

				content.addComponent(pagingControls);
				content.setExpandRatio(pagingControls, ContentRatio.SMALL2);

			}

	/**
	 * Adds the paging link.
	 *
	 * @param label          the label
	 * @param name           the name
	 * @param pageId         the page id
	 * @param maxPages       the max pages
	 * @param pagingControls the paging controls
	 */
	private void addPagingLink(final String label, final String name, final String pageId, final long maxPages, final HorizontalLayout pagingControls) {
		final Link previousPageLink = pageLinkFactory.createAdminPagingLink(label,name, pageId, String.valueOf(maxPages));
		pagingControls.addComponent(previousPageLink);
		pagingControls.setExpandRatio(previousPageLink, ContentRatio.SMALL);
	}

}


/*
 * Copyright 2010 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2019.02.24 at 11:40:17 PM CET
//

package com.hack23.cia.model.external.riksdagen.voteringlista.impl;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;

/**
 * A factory for creating Object objects.
 */
@XmlRegistry
public class ObjectFactory {

    /** The Constant _Voteringlista_QNAME. */
    private static final QName _Voteringlista_QNAME = new QName("http://voteringlista.riksdagen.external.model.cia.hack23.com/impl", "voteringlista");

    /**
	 * Instantiates a new object factory.
	 */
    public ObjectFactory() {
    }

    /**
	 * Creates a new Object object.
	 *
	 * @return the vote list container element
	 */
    public VoteListContainerElement createVoteListContainerElement() {
        return new VoteListContainerElement();
    }

    /**
	 * Creates a new Object object.
	 *
	 * @return the ballot document element
	 */
    public BallotDocumentElement createBallotDocumentElement() {
        return new BallotDocumentElement();
    }

    /**
	 * Creates a new Object object.
	 *
	 * @param value the value
	 * @return the JAXB element< vote list container element>
	 */
    @XmlElementDecl(namespace = "http://voteringlista.riksdagen.external.model.cia.hack23.com/impl", name = "voteringlista")
    public JAXBElement<VoteListContainerElement> createVoteringlista(final VoteListContainerElement value) {
        return new JAXBElement<>(_Voteringlista_QNAME, VoteListContainerElement.class, null, value);
    }

}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.service.data.impl;

import java.util.Locale;

import org.apache.commons.lang.StringUtils;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

/**
 * The Class LegacyNamingStrategy.
 */
public final class LegacyNamingStrategy implements PhysicalNamingStrategy {

    private static final String REG_EXPR = "([a-z])([A-Z])";
    private static final String REPLACEMENT_PATTERN = "$1_$2";

    /**
	 * Instantiates a new legacy naming strategy.
	 */
    public LegacyNamingStrategy() {
		super();
	}

    /**
	 * Convert.
	 *
	 * @param identifier
	 *            the identifier
	 * @return the identifier
	 */
    private static Identifier convert(final Identifier identifier) {
    	if (identifier == null || StringUtils.isBlank(identifier.getText())) {
            return identifier;
        } else {
        	return Identifier.toIdentifier(identifier.getText().replaceAll(REG_EXPR, REPLACEMENT_PATTERN).toLowerCase(Locale.ENGLISH));
        }
    }

    @Override
    public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.service.impl.rules;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenCommitteeBallotDecisionPartySummary;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenCommitteeBallotDecisionPartySummary_;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenCommitteeBallotDecisionPoliticianSummary;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenCommitteeBallotDecisionPoliticianSummary_;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenVoteDataBallotPartySummaryAnnual;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenVoteDataBallotPartySummaryDaily;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenVoteDataBallotPartySummaryMonthly;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenVoteDataBallotPoliticianSummaryAnnual;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenVoteDataBallotPoliticianSummaryDaily;
import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenVoteDataBallotPoliticianSummaryMonthly;
import com.hack23.cia.model.internal.application.data.party.impl.ViewRiksdagenPartySummary;
import com.hack23.cia.model.internal.application.data.politician.impl.ViewRiksdagenPolitician;
import com.hack23.cia.service.api.action.kpi.ComplianceCheck;
import com.hack23.cia.service.data.api.DataViewer;

/**
 * The Class RulesEngineImpl.
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, timeout = 1200)
public final class RulesEngineImpl implements RulesEngine {

	/** The data viewer. */
	@Autowired
	@Qualifier("DataViewer")
	private DataViewer dataViewer;

	@Autowired
	private KieContainer rulesContainer;

	/**
	 * Instantiates a new rules engine impl.
	 */
	public RulesEngineImpl() {
		super();
	}

	@Override
	@Cacheable("checkRulesCompliance")
	public List<ComplianceCheck> checkRulesCompliance() {
		final KieSession ksession = rulesContainer.newKieSession();
		final Map<String, ComplianceCheck> complianceChecks = new HashMap<>();
		ksession.addEventListener(new ComplianceCheckAgendaEventListener(complianceChecks));

		insertPoliticians(ksession, dataViewer.getAll(ViewRiksdagenPolitician.class));
		insertParties(ksession, dataViewer.getAll(ViewRiksdagenPartySummary.class));

		ksession.fireAllRules();
		ksession.dispose();
		return new ArrayList<>(complianceChecks.values());
	}

	/**
	 * Insert politicians.
	 *
	 * @param ksession the ksession
	 * @param list     the list
	 */
	private void insertPoliticians(final KieSession ksession, final List<ViewRiksdagenPolitician> list) {

		final Map<String, List<ViewRiksdagenVoteDataBallotPoliticianSummaryAnnual>> politicanBallotSummaryAnnualMap = dataViewer
				.getAll(ViewRiksdagenVoteDataBallotPoliticianSummaryAnnual.class).stream()
				.collect(Collectors.groupingBy(p -> p.getEmbeddedId().getIntressentId()));
		final Map<String, List<ViewRiksdagenVoteDataBallotPoliticianSummaryMonthly>> politicanBallotSummaryMontlyMap = dataViewer
				.getAll(ViewRiksdagenVoteDataBallotPoliticianSummaryMonthly.class).stream()
				.collect(Collectors.groupingBy(p -> p.getEmbeddedId().getIntressentId()));

		final Map<String, List<ViewRiksdagenVoteDataBallotPoliticianSummaryDaily>> politicanBallotSummaryDailyMap = dataViewer
				.getAll(ViewRiksdagenVoteDataBallotPoliticianSummaryDaily.class).stream()
				.collect(Collectors.groupingBy(p -> p.getEmbeddedId().getIntressentId()));

		final Map<String, List<ViewRiksdagenCommitteeBallotDecisionPoliticianSummary>> decisionMap = dataViewer
				.findListByProperty(ViewRiksdagenCommitteeBallotDecisionPoliticianSummary.class,
						new String[] { "2007/08", "FöU15" }, ViewRiksdagenCommitteeBallotDecisionPoliticianSummary_.rm,
						ViewRiksdagenCommitteeBallotDecisionPoliticianSummary_.committeeReport)
				.stream().collect(Collectors.groupingBy(p -> p.getEmbeddedId().getIntressentId()));

		for (final ViewRiksdagenPolitician politicianData : list) {
			if (politicianData != null) {

				List<ViewRiksdagenCommitteeBallotDecisionPoliticianSummary> ballots = decisionMap
						.get(politicianData.getPersonId());
				if (ballots == null) {
					ballots = new ArrayList<>();
				}

				insertPolitician(ksession, politicianData,
						politicanBallotSummaryDailyMap.get(politicianData.getPersonId()),
						politicanBallotSummaryMontlyMap.get(politicianData.getPersonId()),
						politicanBallotSummaryAnnualMap.get(politicianData.getPersonId()), ballots);
			}
		}
	}

	/**
	 * Insert politician.
	 *
	 * @param ksession       the ksession
	 * @param politicianData the politician data
	 * @param dailyList      the daily list
	 * @param monthlyList    the monthly list
	 * @param annualList     the annual list
	 * @param decisionList   the decision list
	 */
	private static void insertPolitician(final KieSession ksession, final ViewRiksdagenPolitician politicianData,
			final List<ViewRiksdagenVoteDataBallotPoliticianSummaryDaily> dailyList,
			final List<ViewRiksdagenVoteDataBallotPoliticianSummaryMonthly> monthlyList,
			final List<ViewRiksdagenVoteDataBallotPoliticianSummaryAnnual> annualList,
			final List<ViewRiksdagenCommitteeBallotDecisionPoliticianSummary> decisionList) {
		if (politicianData.isActiveParliament() && dailyList != null && monthlyList != null && annualList != null) {
			Collections.sort(dailyList,
					(e1, e2) -> e1.getEmbeddedId().getVoteDate().compareTo(e2.getEmbeddedId().getVoteDate()));
			final Optional<ViewRiksdagenVoteDataBallotPoliticianSummaryDaily> dailyListFirst = dailyList.stream()
					.findFirst();

			Collections.sort(monthlyList,
					(e1, e2) -> e1.getEmbeddedId().getVoteDate().compareTo(e2.getEmbeddedId().getVoteDate()));
			final Optional<ViewRiksdagenVoteDataBallotPoliticianSummaryMonthly> monthlyListFirst = monthlyList.stream()
					.findFirst();
			Collections.sort(annualList,
					(e1, e2) -> e1.getEmbeddedId().getVoteDate().compareTo(e2.getEmbeddedId().getVoteDate()));
			final Optional<ViewRiksdagenVoteDataBallotPoliticianSummaryAnnual> annualListFirst = annualList.stream()
					.findFirst();

			if (annualListFirst.isPresent() && monthlyListFirst.isPresent() && dailyListFirst.isPresent()) {
				final PoliticianComplianceCheckImpl politicianComplianceCheckImpl = new PoliticianComplianceCheckImpl(
						politicianData, dailyListFirst.get(), monthlyListFirst.get(), annualListFirst.get(),
						decisionList);
				ksession.insert(politicianComplianceCheckImpl);
			}
		} else {
			final PoliticianComplianceCheckImpl politicianComplianceCheckImpl = new PoliticianComplianceCheckImpl(
					politicianData, null, null, null, new ArrayList<>());
			ksession.insert(politicianComplianceCheckImpl);
		}
	}

	/**
	 * Insert parties.
	 *
	 * @param ksession the ksession
	 * @param list     the list
	 */
	private void insertParties(final KieSession ksession, final List<ViewRiksdagenPartySummary> list) {
		final Map<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>> politicanBallotSummaryAnnualMap = dataViewer
				.getAll(ViewRiksdagenVoteDataBallotPartySummaryDaily.class).stream()
				.collect(Collectors.groupingBy(p -> p.getEmbeddedId().getParty()));
		final Map<String, List<ViewRiksdagenVoteDataBallotPartySummaryMonthly>> politicanBallotSummaryMontlyMap = dataViewer
				.getAll(ViewRiksdagenVoteDataBallotPartySummaryMonthly.class).stream()
				.collect(Collectors.groupingBy(p -> p.getEmbeddedId().getParty()));
		final Map<String, List<ViewRiksdagenVoteDataBallotPartySummaryAnnual>> politicanBallotSummaryDailyMap = dataViewer
				.getAll(ViewRiksdagenVoteDataBallotPartySummaryAnnual.class).stream()
				.collect(Collectors.groupingBy(p -> p.getEmbeddedId().getParty()));

		final Map<String, List<ViewRiksdagenCommitteeBallotDecisionPartySummary>> decisionMap = dataViewer
				.findListByProperty(ViewRiksdagenCommitteeBallotDecisionPartySummary.class,
						new String[] { "2007/08", "FöU15" }, ViewRiksdagenCommitteeBallotDecisionPartySummary_.rm,
						ViewRiksdagenCommitteeBallotDecisionPartySummary_.committeeReport)
				.stream().collect(Collectors.groupingBy(p -> p.getEmbeddedId().getParty()));

		for (final ViewRiksdagenPartySummary partyData : list) {
			if (partyData != null) {

				List<ViewRiksdagenCommitteeBallotDecisionPartySummary> ballotDecisions = decisionMap
						.get(partyData.getParty());
				if (ballotDecisions == null) {
					ballotDecisions = new ArrayList<>();
				}

				insertParty(ksession, partyData, politicanBallotSummaryDailyMap.get(partyData.getParty()),
						politicanBallotSummaryMontlyMap.get(partyData.getParty()),
						politicanBallotSummaryAnnualMap.get(partyData.getParty()), ballotDecisions);
			}
		}
	}

	/**
	 * Insert party.
	 *
	 * @param ksession        the ksession
	 * @param partyData       the party data
	 * @param dailyList       the daily list
	 * @param monthlyList     the monthly list
	 * @param annualList      the annual list
	 * @param ballotDecisions the ballot decisions
	 */
	private static void insertParty(final KieSession ksession, final ViewRiksdagenPartySummary partyData,
			final List<ViewRiksdagenVoteDataBallotPartySummaryAnnual> dailyList,
			final List<ViewRiksdagenVoteDataBallotPartySummaryMonthly> monthlyList,
			final List<ViewRiksdagenVoteDataBallotPartySummaryDaily> annualList,
			final List<ViewRiksdagenCommitteeBallotDecisionPartySummary> ballotDecisions) {
		if (partyData.isActiveParliament() && dailyList != null && monthlyList != null && annualList != null) {
			Collections.sort(dailyList,
					(e1, e2) -> e1.getEmbeddedId().getVoteDate().compareTo(e2.getEmbeddedId().getVoteDate()));
			final Optional<ViewRiksdagenVoteDataBallotPartySummaryAnnual> dailyListFirst = dailyList.stream()
					.findFirst();
			Collections.sort(monthlyList,
					(e1, e2) -> e1.getEmbeddedId().getVoteDate().compareTo(e2.getEmbeddedId().getVoteDate()));
			final Optional<ViewRiksdagenVoteDataBallotPartySummaryMonthly> monthlyListFirst = monthlyList.stream()
					.findFirst();
			Collections.sort(annualList,
					(e1, e2) -> e1.getEmbeddedId().getVoteDate().compareTo(e2.getEmbeddedId().getVoteDate()));
			final Optional<ViewRiksdagenVoteDataBallotPartySummaryDaily> annualListFirst = annualList.stream()
					.findFirst();

			if (annualListFirst.isPresent() && monthlyListFirst.isPresent() && dailyListFirst.isPresent()) {
				final PartyComplianceCheckImpl politicianComplianceCheckImpl = new PartyComplianceCheckImpl(partyData,
						dailyListFirst.get(), monthlyListFirst.get(), annualListFirst.get(), ballotDecisions);
				ksession.insert(politicianComplianceCheckImpl);
			}
		} else {
			final PartyComplianceCheckImpl politicianComplianceCheckImpl = new PartyComplianceCheckImpl(partyData, null,
					null, null, new ArrayList<>());
			ksession.insert(politicianComplianceCheckImpl);
		}
	}
}


/*
 * Copyright 2010-2019 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
package com.hack23.cia.service.external.riksdagen.impl;

import javax.xml.bind.JAXBElement;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.oxm.Unmarshaller;
import org.springframework.stereotype.Component;

import com.hack23.cia.model.external.riksdagen.utskottsforslag.impl.CommitteeProposalComponentData;
import com.hack23.cia.service.external.common.api.XmlAgent;
import com.hack23.cia.service.external.common.api.XmlAgentException;
import com.hack23.cia.service.external.riksdagen.api.DataFailureException;
import com.hack23.cia.service.external.riksdagen.api.RiksdagenCommitteeProposalApi;

/**
 * The Class RiksdagenCommitteeProposalApiImpl.
 */
@Component
final class RiksdagenCommitteeProposalApiImpl implements RiksdagenCommitteeProposalApi {

	/** The Constant COMMITTE_PROPOSAL. */
	private static final String COMMITTE_PROPOSAL = "https://data.riksdagen.se/utskottsforslag/${ID_KEY}/xml";

	/**
	 * The Constant
	 * HTTP_UTSKOTTSFORSLAG_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL.
	 */
	private static final String HTTP_UTSKOTTSFORSLAG_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL = "http://utskottsforslag.riksdagen.external.model.cia.hack23.com/impl";

	/** The Constant ID_KEY. */
	private static final String ID_KEY = "${ID_KEY}";

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory.getLogger(RiksdagenCommitteeProposalApiImpl.class);

	/**
	 * The Constant
	 * PROBLEM_GETTING_COMMITTEE_PROPOSAL_FOR_ID_S_FROM_DATA_RIKSDAGEN_SE.
	 */
	private static final String PROBLEM_GETTING_COMMITTEE_PROPOSAL_FOR_ID_S_FROM_DATA_RIKSDAGEN_SE = "Problem getting committee proposal for id:{} from data.riksdagen.se";

	/** The riksdagen committee proposal marshaller. */
	@Autowired
	@Qualifier("riksdagenCommitteeProposalMarshaller")
	private Unmarshaller riksdagenCommitteeProposalMarshaller;

	/** The xml agent. */
	private final XmlAgent xmlAgent;

	/**
	 * Instantiates a new riksdagen committee proposal api impl.
	 *
	 * @param xmlAgent
	 *            the xml agent
	 */
	@Autowired
	public RiksdagenCommitteeProposalApiImpl(final XmlAgent xmlAgent) {
		super();
		this.xmlAgent = xmlAgent;
	}

	/* (non-Javadoc)
	 * @see com.hack23.cia.service.external.riksdagen.api.RiksdagenCommitteeProposalApi#getCommitteeProposal(java.lang.String)
	 */
	@Override
	public CommitteeProposalComponentData getCommitteeProposal(final String id) throws DataFailureException {
		try {
			final String url = COMMITTE_PROPOSAL.replace(ID_KEY, id);
			return ((JAXBElement<CommitteeProposalComponentData>) xmlAgent.unmarshallXml(
					riksdagenCommitteeProposalMarshaller, url,
					HTTP_UTSKOTTSFORSLAG_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL, null, null)).getValue();
		} catch (final XmlAgentException e) {
			LOGGER.warn(PROBLEM_GETTING_COMMITTEE_PROPOSAL_FOR_ID_S_FROM_DATA_RIKSDAGEN_SE, id);
			throw new DataFailureException(e);
		}
	}

}


/*
 * Copyright 2010 James Pether Sörling
 *
 * 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.
 *
 *	$Id$
 *  $HeadURL$
*/
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2019.02.24 at 11:40:10 PM CET
//

package com.hack23.cia.model.external.riksdagen.utskottsforslag.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.hack23.cia.model.common.api.ModelObject;

/**
 * The Class AgainstProposalContainer.
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AgainstProposalContainer", propOrder = {
    "againstProposalList"
})
@Entity(name = "AgainstProposalContainer")
@Table(name = "AGAINST_PROPOSAL_CONTAINER")
@Inheritance(strategy = InheritanceType.JOINED)
public class AgainstProposalContainer
    implements ModelObject
{

    /**
	 *
	 */
	private static final long serialVersionUID = 1L;

	/** The against proposal list. */
    @XmlElement(name = "motforslag", required = true)
    protected List<AgainstProposalData> againstProposalList = new ArrayList<>();

    /** The hjid. */
    @XmlAttribute(name = "Hjid")
    protected Long hjid;

    /**
	 * Gets the against proposal list.
	 *
	 * @return the against proposal list
	 */
    @OneToMany(targetEntity = AgainstProposalData.class, cascade = {
        CascadeType.ALL
    })
    @JoinColumn(name = "AGAINST_PROPOSAL_LIST_AGAINS_0")
    public List<AgainstProposalData> getAgainstProposalList() {
        return this.againstProposalList;
    }

    /**
	 * Sets the against proposal list.
	 *
	 * @param againstProposalList the new against proposal list
	 */
    public void setAgainstProposalList(final List<AgainstProposalData> againstProposalList) {
        this.againstProposalList = againstProposalList;
    }

    /**
	 * With against proposal list.
	 *
	 * @param againstProposalList the against proposal list
	 * @return the against proposal container
	 */
    public AgainstProposalContainer withAgainstProposalList(final List<AgainstProposalData> againstProposalList) {
        setAgainstProposalList(againstProposalList);
        return this;
    }

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public final String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}

    /**
	 * Gets the hjid.
	 *
	 * @return the hjid
	 */
    @Id
    @Column(name = "HJID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getHjid() {
        return hjid;
    }

    /**
	 * Sets the hjid.
	 *
	 * @param value the new hjid
	 */
    public void setHjid(final Long value) {
        this.hjid = value;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(final Object object) {
    	return EqualsBuilder.reflectionEquals(this,object,"hjid");
    }

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public final int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this);
	}

}