09595731c61285de836be8d27ae003ebbc35f72a
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / UpdateResult.java
1 /**
2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.api.service;
10
11 import java.io.Serializable;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Set;
17 import java.util.UUID;
18
19 import org.apache.commons.collections4.queue.CircularFifoQueue;
20 import org.apache.logging.log4j.LogManager;
21 import org.apache.logging.log4j.Logger;
22
23 import eu.etaxonomy.cdm.api.service.dto.CdmEntityIdentifier;
24 import eu.etaxonomy.cdm.common.CdmUtils;
25 import eu.etaxonomy.cdm.model.common.CdmBase;
26 import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
27
28 /**
29 * This class represents the result of an update action.
30 *
31 * @author k.luther
32 * @since 11.02.2015
33 */
34 public class UpdateResult implements Serializable{
35
36 private static final long serialVersionUID = -7040027587709706700L;
37
38 @SuppressWarnings("unused")
39 private static final Logger logger = LogManager.getLogger(UpdateResult.class);
40
41 private Status status = Status.OK;
42
43 private final Collection<Exception> exceptions = new CircularFifoQueue<>(10);
44
45 private Set<CdmBase> updatedObjects = new HashSet<>();
46
47 private final Set<CdmEntityIdentifier> updatedCdmIds = new HashSet<>();
48
49 private final Set<CdmBase> unchangedObjects = new HashSet<>();
50
51 private CdmBase cdmEntity;
52
53 private Map<Class<? extends CdmBase>, Set<UUID>> insertedUuids = new HashMap<>();
54 private Map<Class<? extends CdmBase>, Set<UUID>> updatedUuids = new HashMap<>();
55
56 public enum Status {
57 OK(0),
58 ABORT(1),
59 ERROR(3),
60 ;
61
62 protected Integer severity;
63 private Status(int severity){
64 this.severity = severity;
65 }
66
67 public int compareSeverity(Status other){
68 return this.severity.compareTo(other.severity);
69 }
70 }
71
72 //***************************** GETTER /SETTER /ADDER *************************/
73
74 /**
75 * The resulting status of an update action.
76 *
77 * @see UpdateStatus
78 * @return
79 */
80 public Status getStatus() {
81 return status;
82 }
83 public void setStatus(Status status) {
84 this.status = status;
85 }
86
87 /**
88 * The highest exception that occurred during delete (if any).
89 */
90 public Collection<Exception> getExceptions() {
91 return exceptions;
92 }
93 public void addException(Exception exception) {
94 this.exceptions.add(exception);
95 }
96 public void addExceptions(Collection<Exception> exceptions) {
97 this.exceptions.addAll(exceptions);
98 }
99
100 //inserted object UUIDs
101 public Map<Class<? extends CdmBase>, Set<UUID>> getInsertedUuids(){
102 return this.insertedUuids;
103 }
104 public void addInsertedUuid(CdmBase cdmBase) {
105 Class<? extends CdmBase> clazz = CdmBase.deproxy(cdmBase).getClass();
106 initClassRecord(insertedUuids, clazz);
107 this.insertedUuids.get(clazz).add(cdmBase.getUuid());
108 }
109 public Set<UUID> getInsertedUuids(Class<? extends CdmBase> clazz){
110 return byMapKey(this.insertedUuids, clazz);
111 }
112
113 //updated object UUIDs
114 public Map<Class<? extends CdmBase>, Set<UUID>> getUpdatedUuids(){
115 return this.updatedUuids;
116 }
117 public void addUpdatedUuid(CdmBase cdmBase) {
118 Class<? extends CdmBase> clazz = CdmBase.deproxy(cdmBase).getClass();
119 initClassRecord(updatedUuids, clazz);
120 this.updatedUuids.get(clazz).add(cdmBase.getUuid());
121 }
122 public Set<UUID> getUpdatedUuids(Class<? extends CdmBase> clazz){
123 return byMapKey(this.updatedUuids, clazz);
124 }
125
126 public Set<UUID> getInsertedOrUpdatedUuids(Class<? extends CdmBase> clazz){
127 HashSet<UUID> result = new HashSet<UUID>(getUpdatedUuids(clazz));
128 result.addAll(getInsertedUuids(clazz));
129 return result;
130 }
131
132 private void initClassRecord(Map<Class<? extends CdmBase>, Set<UUID>> map, Class<? extends CdmBase> clazz){
133 if (map.get(clazz) == null){
134 map.put(clazz, new HashSet<>());
135 }
136 }
137 private Set<UUID> byMapKey(Map<Class<? extends CdmBase>, Set<UUID>> map, Class<? extends CdmBase> clazz){
138 return map.get(clazz) == null ? new HashSet<>() : map.get(clazz);
139 }
140
141 //updated CDM id-s
142 public Set<CdmEntityIdentifier> getUpdatedCdmIds() {
143 return updatedCdmIds;
144 }
145 public void addUpdatedCdmId(CdmEntityIdentifier cdmId) {
146 this.updatedCdmIds.add(cdmId);
147 }
148 public void addUpdatedCdmIds(Set<CdmEntityIdentifier> updatedCdmIds) {
149 this.updatedCdmIds.addAll(updatedCdmIds);
150 }
151 public void addUpdatedCdmId(CdmBase updatedObject) {
152 this.updatedCdmIds.add(CdmEntityIdentifier.NewInstance(updatedObject));
153 }
154
155 //updated objects
156 public Set<CdmBase> getUpdatedObjects() {
157 return updatedObjects;
158 }
159 public void addUpdatedObject(CdmBase relatedObject) {
160 this.updatedObjects.add(relatedObject);
161 }
162 public void addUpdatedObjects(Set<? extends CdmBase> updatedObjects) {
163 this.updatedObjects.addAll(updatedObjects);
164 }
165
166
167 //cdmEntity
168 public void setCdmEntity(CdmBase cdmBase) {
169 this.cdmEntity = cdmBase;
170 }
171 public CdmBase getCdmEntity(){
172 return cdmEntity;
173 }
174
175 //unchanged objects
176 public Set<CdmBase> getUnchangedObjects() {
177 return unchangedObjects;
178 }
179 public void addUnchangedObjects(Set<? extends CdmBase> unchangedObjects) {
180 this.unchangedObjects.addAll(unchangedObjects);
181 }
182 public void addUnChangedObject(CdmBase unchangedObject) {
183 this.unchangedObjects.add(unchangedObject);
184 }
185
186 //****************** CONVENIENCE *********************************************/
187
188 /**
189 * Sets the status to {@link Status#ERROR} if not yet set to a more serious
190 * status.
191 */
192 public void setError(){
193 setMaxStatus(Status.ERROR);
194 }
195
196 /**
197 * Sets the status to {@link Status#ABORT} if not yet set to a more serious
198 * status.
199 */
200 public void setAbort(){
201 setMaxStatus(Status.ABORT);
202 }
203
204 /**
205 * Sets status to most severe status. If maxStatus is more severe then existing status
206 * existing status is set to maxStatus. Otherwise nothing changes.
207 * If minStatus is more severe then given status minStatus will be the new status.
208 * @param maxStatus
209 */
210 public void setMaxStatus(Status maxStatus) {
211 if (this.status.compareSeverity(maxStatus) < 0){
212 this.status = maxStatus;
213 }
214 }
215
216 public void includeResult(UpdateResult includedResult){
217 includeResult(includedResult, false);
218 }
219
220 public void includeResult(UpdateResult includedResult, boolean excludeStatusAndException){
221
222 if (!excludeStatusAndException){
223 this.setMaxStatus(includedResult.getStatus());
224 this.addExceptions(includedResult.getExceptions());
225 }
226 this.addUpdatedObjects(includedResult.getUpdatedObjects());
227 this.addUpdatedCdmIds(includedResult.getUpdatedCdmIds());
228 //also add cdm entity of included result to updated objects
229 if(includedResult.getCdmEntity()!=null){
230 this.getUpdatedObjects().add(includedResult.getCdmEntity());
231 }
232 }
233
234 public boolean isOk(){
235 return this.status == Status.OK;
236 }
237
238 public boolean isAbort(){
239 return this.status == Status.ABORT;
240 }
241
242 public boolean isError(){
243 return this.status == Status.ERROR;
244 }
245
246 // *********************************** TO STRING ***************************************/
247 @Override
248 public String toString(){
249 String separator = ", ";
250 String exceptionString = "";
251 for (Exception exception : exceptions) {
252 exceptionString += exception.getLocalizedMessage()+separator;
253 }
254 if(exceptionString.endsWith(separator)){
255 exceptionString = exceptionString.substring(0, exceptionString.length()-separator.length());
256 }
257 String updatedObjectString = toStringObjectsString(separator, updatedObjects);
258 String unchangedObjectString = toStringObjectsString(separator, unchangedObjects);
259 return "[UpdateResult]\n" +
260 "Status: " + status.toString()+"\n" +
261 "Exceptions: " + exceptionString+"\n" +
262 "Updated objects: " + updatedObjectString+"\n" +
263 "Updated objects IDs: " + toStringIdsString(separator, updatedCdmIds)+"\n" +
264 "Unchanged objects: " + unchangedObjectString
265 ;
266 }
267
268 private String toStringIdsString(String separator, Set<CdmEntityIdentifier> cdmIds) {
269 String result = "";
270 for (CdmEntityIdentifier id : cdmIds){
271 result = CdmUtils.concat(separator, result, id.toString());
272 }
273 return result;
274 }
275 /**
276 * Serializes the CdmBase collection
277 */
278 protected static String toStringObjectsString(String separator, Set<CdmBase> cdmBases) {
279 String cdmBasesString = "";
280 for (CdmBase cdmBase: cdmBases) {
281 if(cdmBase instanceof IIdentifiableEntity){
282 cdmBasesString += ((IIdentifiableEntity) cdmBase).getTitleCache()+separator;
283 }
284 else{
285 cdmBasesString += cdmBase.toString()+separator;
286 }
287 }
288 if(cdmBasesString.endsWith(separator)){
289 cdmBasesString = cdmBasesString.substring(0, cdmBasesString.length()-separator.length());
290 }
291 return cdmBasesString;
292 }
293 }