Project

General

Profile

Download (10.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 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.util.ArrayList;
12
import java.util.List;
13
import java.util.UUID;
14

    
15
import org.apache.log4j.Logger;
16
import org.springframework.beans.factory.annotation.Autowired;
17
import org.springframework.stereotype.Service;
18
import org.springframework.transaction.annotation.Transactional;
19

    
20
import eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator;
21
import eu.etaxonomy.cdm.api.service.pager.Pager;
22
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
23
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
24
import eu.etaxonomy.cdm.model.agent.Address;
25
import eu.etaxonomy.cdm.model.agent.AgentBase;
26
import eu.etaxonomy.cdm.model.agent.Institution;
27
import eu.etaxonomy.cdm.model.agent.InstitutionalMembership;
28
import eu.etaxonomy.cdm.model.agent.Person;
29
import eu.etaxonomy.cdm.model.agent.Team;
30
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
31
import eu.etaxonomy.cdm.model.common.CdmBase;
32
import eu.etaxonomy.cdm.persistence.dao.agent.IAgentDao;
33
import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;
34
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
35
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
36
import eu.etaxonomy.cdm.strategy.merge.ConvertMergeStrategy;
37
import eu.etaxonomy.cdm.strategy.merge.DefaultMergeStrategy;
38
import eu.etaxonomy.cdm.strategy.merge.IMergeStrategy;
39
import eu.etaxonomy.cdm.strategy.merge.MergeException;
40
import eu.etaxonomy.cdm.strategy.merge.MergeMode;
41

    
42
/**
43
 * @author a.mueller
44
 */
45
@Service
46
@Transactional(readOnly = true)
47
public class AgentServiceImpl
48
        extends IdentifiableServiceBase<AgentBase,IAgentDao>
49
        implements IAgentService {
50

    
51
    private static final Logger logger = Logger.getLogger(AgentServiceImpl.class);
52

    
53
    @Autowired
54
    private ICdmGenericDao genericDao;
55

    
56
	@Override
57
    @Autowired
58
	protected void setDao(IAgentDao dao) {
59
		assert dao != null;
60
		this.dao = dao;
61
	}
62

    
63
 	/**
64
	 * Constructor
65
	 */
66
	public AgentServiceImpl(){
67
		if (logger.isDebugEnabled()) { logger.debug("Load AgentService Bean"); }
68
	}
69

    
70
	@Override
71
	@Transactional(readOnly = false)
72
    public UpdateResult updateCaches(Class<? extends AgentBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<AgentBase> cacheStrategy, IProgressMonitor monitor) {
73
		if (clazz == null){
74
			clazz = AgentBase.class;
75
		}
76
		return super.updateCachesImpl(clazz, stepSize, cacheStrategy, monitor);
77
	}
78

    
79
	@Override
80
	public List<Institution> searchInstitutionByCode(String code) {
81
		return dao.getInstitutionByCode(code);
82
	}
83

    
84
	@Override
85
	public Pager<InstitutionalMembership> getInstitutionalMemberships(Person person, Integer pageSize, Integer pageNumber) {
86
        long numberOfResults = dao.countInstitutionalMemberships(person);
87

    
88
		List<InstitutionalMembership> results = new ArrayList<>();
89
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
90
			results = dao.getInstitutionalMemberships(person, pageSize, pageNumber);
91
		}
92

    
93
		return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
94
	}
95

    
96
	@Override
97
	public Pager<Person> getMembers(Team team, Integer pageSize, Integer pageNumber) {
98
		long numberOfResults = dao.countMembers(team);
99

    
100
		List<Person> results = new ArrayList<>();
101
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
102
			results = dao.getMembers(team, pageSize, pageNumber);
103
		}
104

    
105
		return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
106
	}
107

    
108
	@Override
109
	public Pager<Address> getAddresses(AgentBase agent, Integer pageSize, Integer pageNumber) {
110
		long numberOfResults = dao.countAddresses(agent);
111

    
112
		List<Address> results = new ArrayList<>();
113
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
114
			results = dao.getAddresses(agent, pageSize, pageNumber);
115
		}
116

    
117
		return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
118
	}
119

    
120
	@Override
121
	public List<UuidAndTitleCache<Team>> getTeamUuidAndNomenclaturalTitle() {
122
		return dao.getTeamUuidAndNomenclaturalTitle();
123
	}
124

    
125
	@Override
126
	public List<UuidAndTitleCache<Person>> getPersonUuidAndTitleCache() {
127
		return dao.getPersonUuidAndTitleCache();
128
	}
129

    
130
	@Override
131
	public List<UuidAndTitleCache<Team>> getTeamUuidAndTitleCache() {
132
		return dao.getTeamUuidAndTitleCache();
133
	}
134

    
135
	@Override
136
	public List<UuidAndTitleCache<Institution>> getInstitutionUuidAndTitleCache(Integer limit, String pattern) {
137
		return dao.getUuidAndAbbrevTitleCache(Institution.class, limit, pattern);
138
	}
139

    
140
	@Override
141
	@Transactional(readOnly = false)
142
    public DeleteResult delete(UUID agentUUID){
143
	    DeleteResult result = new DeleteResult();
144
	    if (agentUUID == null){
145
	        result.setAbort();
146
	        result.addException(new Exception("Can't delete object without UUID."));
147
	        return result;
148
	    }
149
		AgentBase base = dao.load(agentUUID);
150
		result = isDeletable(agentUUID, null);
151

    
152
    	if (result.isOk()){
153
			if (base instanceof Team){
154
				Team baseTeam = (Team) base;
155
				List<Person> members = baseTeam.getTeamMembers();
156
				List<Person> temp = new ArrayList<>();
157
				for (Person member:members){
158
					temp.add(member);
159
				}
160
				for (Person member: temp){
161
					members.remove(member);
162
				}
163
			}
164
			saveOrUpdate(base);
165

    
166
			dao.delete(base);
167
			result.addDeletedObject(base);
168

    
169
		}
170

    
171
		return result;
172
    }
173

    
174
	@Override
175
    public DeleteResult delete(AgentBase agent){
176
		return delete(agent.getUuid());
177
	}
178

    
179
	@Override
180
	@Transactional(readOnly = false)
181
	public UpdateResult convertTeam2Person(UUID teamUuid) throws MergeException {
182
	    Team team = CdmBase.deproxy(dao.load(teamUuid), Team.class);
183
	    return convertTeam2Person(team);
184
	}
185

    
186
	@Override
187
	public UpdateResult convertTeam2Person(Team team) throws MergeException {
188
        UpdateResult result = new UpdateResult();
189
        Person newPerson = null;
190
		team = CdmBase.deproxy(team, Team.class);
191
		if (team.getTeamMembers().size() > 1){
192
			throw new IllegalArgumentException("Team must not have more than 1 member to be convertable into a person");
193
		}else if (team.getTeamMembers().size() == 1){
194
		    newPerson = team.getTeamMembers().get(0);
195
			IMergeStrategy strategy = DefaultMergeStrategy.NewInstance(TeamOrPersonBase.class);
196
			strategy.setDefaultCollectionMergeMode(MergeMode.FIRST);
197
			genericDao.merge(newPerson, team, strategy);
198
		}else if (team.getTeamMembers().isEmpty()){
199
		    newPerson = Person.NewInstance();
200
            genericDao.save(newPerson);
201
			IMergeStrategy strategy = DefaultMergeStrategy.NewInstance(TeamOrPersonBase.class);
202
			strategy.setDefaultMergeMode(MergeMode.SECOND);
203
			strategy.setDefaultCollectionMergeMode(MergeMode.SECOND);
204
			genericDao.merge(newPerson, team, strategy);
205
		}else{
206
			throw new IllegalStateException("Unhandled state of team members collection");
207
		}
208
		result.setCdmEntity(newPerson);
209
		return result;
210
	}
211

    
212
	@Override
213
	@Transactional(readOnly = false)
214
	public UpdateResult convertPerson2Team(UUID personUuid) throws MergeException, IllegalArgumentException {
215
	    Person person = CdmBase.deproxy(dao.load(personUuid), Person.class);
216
	    return convertPerson2Team(person);
217
	}
218

    
219
	@Override
220
	public UpdateResult convertPerson2Team(Person person) throws MergeException, IllegalArgumentException {
221
	    if (person == null){
222
	        throw new IllegalArgumentException("Person does not exist.");
223
	    }
224
	    UpdateResult result = new UpdateResult();
225
        Team team = Team.NewInstance();
226
        ConvertMergeStrategy strategy = ConvertMergeStrategy.NewInstance(TeamOrPersonBase.class);
227
        strategy.setDefaultMergeMode(MergeMode.SECOND);
228
        strategy.setDefaultCollectionMergeMode(MergeMode.SECOND);
229
        if (person.isProtectedTitleCache() || !person.getTitleCache().startsWith("Person#")){  //the later is for checking if the person is empty, this can be done better
230
            team.setTitleCache(person.getTitleCache(), true);  //as there are no members we set the titleCache to protected (as long as titleCache does not take the protected nomenclatural title but results in '-empty team-' in this situation); for some reason it is necessary to also set the title cache as well here, otherwise it is recomputed during the merge
231
        }
232
        strategy.setMergeMode("protectedTitleCache", MergeMode.FIRST); //as we do not add team members, the titleCache of the new team should be always protected
233
        strategy.setDeleteSecondObject(true);
234
        team.setNomenclaturalTitle(person.getNomenclaturalTitle(), true);  //sets the protected flag always to true, this is necessary as long as person does not have a nomenclatural title cache; maybe setting the protected title itself is not necessary but does no harm
235

    
236
        if (! genericDao.isMergeable(team, person, strategy)){
237
			throw new MergeException("Person can not be transformed into team.");
238
		}
239
		try {
240
			team = this.save(team);
241
			genericDao.merge(team, person, strategy);
242

    
243
			//Note: we decided  never add the old person as (first) member of the team as there are not many usecases for this.
244
			//But we may try to parse the old person into members which may handle the case that teams have been stored as unparsed persons
245

    
246
		} catch (Exception e) {
247
			throw new MergeException("Unhandled merge exception", e);
248
		}
249
		result.setCdmEntity(team);
250
		result.addUpdatedObject(team);
251
        return result;
252
	}
253

    
254
    @Override
255
    public <T extends AgentBase> List<UuidAndTitleCache<T>> getUuidAndAbbrevTitleCache(Class<T> clazz, Integer limit, String pattern) {
256
        return dao.getUuidAndAbbrevTitleCache(clazz, null, pattern);
257
    }
258

    
259
    @Override
260
    public <T extends AgentBase<?>> List<T> findByTitleAndAbbrevTitle(IIdentifiableEntityServiceConfigurator<T> config){
261
        return dao.findByTitleAndAbbrevTitle(config.getClazz(),config.getTitleSearchStringSqlized(), config.getMatchMode(), config.getCriteria(), config.getPageSize(), config.getPageNumber(), config.getOrderHints(), config.getPropertyPaths());
262
    }
263
}
(1-1/97)