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