1   package com.trendmicro.grid.acl.ds.jpa.entities;
2   
3   import com.trendmicro.grid.acl.Limits;
4   import com.trendmicro.grid.acl.ds.datatypes.SharedJob;
5   import com.trendmicro.grid.acl.metadata.Metadata;
6   import org.hibernate.annotations.Index;
7   import org.hibernate.annotations.Type;
8   
9   import javax.persistence.*;
10  import java.sql.Timestamp;
11  import java.util.Date;
12  import java.util.List;
13  import java.util.UUID;
14  
15  import static com.trendmicro.grid.acl.ds.jpa.util.JpaUtils.fromBytes;
16  import static com.trendmicro.grid.acl.ds.jpa.util.JpaUtils.toBytes;
17  
18  /**
19   * Binds Job to the table "JOBS".
20   *
21   * @author juergen_kellerer, 2010-06-01
22   * @version 1.0
23   */
24  @NamedQueries({
25  		@NamedQuery(name = "Job.SelectById", query = "" +
26  				"SELECT j FROM JOBS j " +
27  				"WHERE 	j.publicGUID = :publicGUID"),
28  
29  		@NamedQuery(name = "Job.SelectJobStateById", query = "" +
30  				"SELECT j.state FROM JOBS j " +
31  				"WHERE 	j.publicGUID = :publicGUID"),
32  
33  		@NamedQuery(name = "Job.SelectJobIdsByState", query = "" +
34  				"SELECT j.publicGUID FROM JOBS j " +
35  				"WHERE 	j.state = :state"),
36  
37  		@NamedQuery(name = "Job.SelectJobIdsByStateInRange", query = "" +
38  				"SELECT j.publicGUID FROM JOBS j " +
39  				"WHERE 	j.state = :state AND j.lastUpdated BETWEEN :fromDate AND :toDate"),
40  
41  		@NamedQuery(name = "Job.SelectJobId", query = "" +
42  				"SELECT j.state FROM JOBS j " +
43  				"WHERE 	j.publicGUID = :publicGUID")
44  })
45  @Cacheable
46  @Entity(name = "JOBS")
47  public class JpaJob extends SharedJob {
48  
49  	private static final long serialVersionUID = 4621907144968629303L;
50  
51  	protected int primaryKey;
52  	protected JpaJob parentJob;
53  	protected List<JpaJob> subJobs;
54  
55  	/**
56  	 * Used by JPA to construct an empty instance.
57  	 */
58  	public JpaJob() {
59  	}
60  
61  	/**
62  	 * Constructs a new JpaJob instance for the given parent job.
63  	 *
64  	 * @param jobId	 the job id of the job to create.
65  	 * @param parentJob the parent job to link this job against.
66  	 */
67  	public JpaJob(UUID jobId, JpaJob parentJob) {
68  		super(jobId, parentJob == null ? null : parentJob.getJobId(), State.PREPARED,
69  				0, new Date(), null, null, null);
70  		this.parentJob = parentJob;
71  	}
72  
73  	@Id
74  	@GeneratedValue
75  	@Column(name = "JOB_ID", nullable = false)
76  	public int getPrimaryKey() {
77  		return primaryKey;
78  	}
79  
80  	public void setPrimaryKey(int primaryKey) {
81  		this.primaryKey = primaryKey;
82  	}
83  
84  	@ManyToOne(fetch = FetchType.LAZY)
85  	@JoinColumn(name = "PARENT_JOB_ID", nullable = true, updatable = false)
86  	public JpaJob getParentJob() {
87  		return parentJob;
88  	}
89  
90  	public void setParentJob(JpaJob parentJob) {
91  		this.parentJob = parentJob;
92  	}
93  
94  	@OneToMany(mappedBy = "parentJob", fetch = FetchType.LAZY)
95  	public List<JpaJob> getSubJobs() {
96  		return subJobs;
97  	}
98  
99  	public void setSubJobs(List<JpaJob> subJobs) {
100 		this.subJobs = subJobs;
101 	}
102 
103 	@Override
104 	@Index(name = "STATE_INDEX")
105 	@Column(name = "STATE", nullable = false)
106 	@Enumerated(EnumType.ORDINAL)
107 	public State getState() {
108 		return state;
109 	}
110 
111 	@Override
112 	public void setState(State state) {
113 		this.state = state;
114 	}
115 
116 	@Override
117 	@Column(name = "STAGE")
118 	public int getStagesPassed() {
119 		return stagesPassed;
120 	}
121 
122 	@Override
123 	public void setStagesPassed(int stagesPassed) { //NOSONAR - Override is required as hook for JPA.
124 		super.setStagesPassed(stagesPassed);
125 	}
126 
127 	@Transient
128 	public void setParentJobId(UUID parentJobId) {
129 		this.parentJobId = parentJobId;
130 	}
131 
132 	@Index(name = "IX_JOBS__PUBLIC_GUID_INDEX")
133 	@Column(name = "PUBLIC_GUID", nullable = false, length = 16)
134 	public byte[] getPublicGUID() {
135 		return toBytes(jobId);
136 	}
137 
138 	public void setPublicGUID(byte[] publicGUID) {
139 		jobId = fromBytes(publicGUID);
140 	}
141 
142 	@Override
143 	@Column(name = "CREATED", nullable = false)
144 	@Temporal(TemporalType.TIMESTAMP)
145 	public Date getCreated() {
146 		return created;
147 	}
148 
149 	public void setCreated(Date created) {
150 		// Note: Converting Timestamp to Date to avoid that "equals()" fails to compare 2 instances.
151 		this.created = created instanceof Timestamp ? new Date(created.getTime()) : created;
152 	}
153 
154 	@Override
155 	@Column(name = "LAST_UPDATED")
156 	@Temporal(TemporalType.TIMESTAMP)
157 	public Date getLastUpdated() {
158 		return lastUpdated;
159 	}
160 
161 	@Override
162 	public void setLastUpdated(Date lastUpdated) { //NOSONAR - Override is required as hook for JPA.
163 		// Note: Converting Timestamp to Date to avoid that "equals()" fails to compare 2 instances.
164 		lastUpdated = lastUpdated instanceof Timestamp ? new Date(lastUpdated.getTime()) : lastUpdated;
165 
166 		super.setLastUpdated(lastUpdated);
167 	}
168 
169 	@Override
170 	@Column(name = "FINISHED")
171 	@Temporal(TemporalType.TIMESTAMP)
172 	public Date getFinished() {
173 		return finished;
174 	}
175 
176 	public void setFinished(Date finished) {
177 		if (this.finished == null) {
178 			// Note: Converting Timestamp to Date to avoid that "equals()" fails to compare 2 instances.
179 			this.finished = finished instanceof Timestamp ? new Date(finished.getTime()) : finished;
180 		}
181 	}
182 
183 	@Override
184 	@Type(type = "metadata")
185 	@Basic(fetch = FetchType.EAGER)
186 	@Column(name = "META_DATA", length = Limits.MAX_SERIALIZED_METADATA_LENGTH)
187 	public Metadata getMetadata() {
188 		return super.getMetadata();
189 	}
190 
191 	@Override
192 	public void setMetadata(Metadata metadata) { //NOSONAR - Override is required as hook for JPA.
193 		super.setMetadata(metadata == null ? null : metadata.clone());
194 	}
195 
196 	@Override
197 	public String toString() {
198 		return "JpaJob{" +
199 				"primaryKey=" + primaryKey +
200 				", jobId=" + jobId +
201 				", parentJobId=" + parentJobId +
202 				", state=" + state +
203 				", stagesPassed=" + stagesPassed +
204 				", parentJobId=" + parentJobId +
205 				", created=" + created +
206 				", lastUpdated=" + lastUpdated +
207 				", finished=" + finished +
208 				", metadata=" + metadata +
209 				", parentJob=" + parentJob +
210 				", subJobs=" + subJobs +
211 				'}';
212 	}
213 }