1 package com.atlassian.jira.issue.link;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.apache.commons.collections.map.LRUMap;
10 import org.apache.log4j.Logger;
11 import org.ofbiz.core.entity.EntityUtil;
12 import org.ofbiz.core.entity.GenericEntityException;
13 import org.ofbiz.core.entity.GenericValue;
14
15 import com.atlassian.core.ofbiz.util.EntityUtils;
16 import com.atlassian.jira.config.ConstantsManager;
17 import com.atlassian.jira.permission.PermissionContextFactory;
18 import com.atlassian.jira.permission.PermissionTypeManager;
19 import com.atlassian.jira.project.ProjectManager;
20 import com.atlassian.jira.scheme.AbstractSchemeManager;
21 import com.atlassian.jira.scheme.SchemeEntity;
22 import com.atlassian.jira.scheme.SchemeFactory;
23 import com.atlassian.jira.util.map.EasyMap;
24 import com.opensymphony.user.User;
25
26
27
28
29
30
31
32
33 public class DefaultLinkSchemeManager extends AbstractSchemeManager implements LinkSchemeManager, LinkConstants {
34
35 private static final Logger log = Logger.getLogger(DefaultLinkSchemeManager.class);
36
37 protected ConstantsManager constantsManager;
38 protected IssueLinkTypeManager issueLinkTypeManager;
39
40 private Map cache;
41
42 public DefaultLinkSchemeManager(ProjectManager projectManager, PermissionTypeManager permissionTypeManager, PermissionContextFactory permissionContextFactory, SchemeFactory schemeFactory, ConstantsManager constantsManager, IssueLinkTypeManager issueLinkTypeManager) {
43 super(projectManager, permissionTypeManager, permissionContextFactory, schemeFactory);
44 this.constantsManager = constantsManager;
45 this.issueLinkTypeManager = issueLinkTypeManager;
46 cache = Collections.synchronizedMap(new LRUMap(1000));
47 }
48
49
50
51
52 public String getSchemeEntityName() {
53 return SCHEME_ENTITY_NAME;
54 }
55
56
57
58
59 public String getEntityName() {
60 return ISSUE_TYPE_LINK_ENTITY_NAME;
61 }
62
63
64
65
66 public String getAssociationType() {
67 return PROJECT_ASSOCIATION;
68 }
69
70
71
72
73 public String getSchemeDesc() {
74 return SCHEME_DESC;
75 }
76
77
78
79
80 public GenericValue copySchemeEntity(GenericValue scheme, GenericValue entity) throws GenericEntityException {
81 SchemeEntity schemeEntity = new SchemeEntity(entity.getString(SCHEME_ENTITY_LINKTYPE), entity.getString(SCHEME_ENTITY_SOURCE), entity.getString(SCHEME_ENTITY_DESTINATION));
82 return createSchemeEntity(scheme, schemeEntity);
83 }
84
85
86
87
88 public GenericValue createSchemeEntity(GenericValue scheme, SchemeEntity schemeEntity) throws GenericEntityException {
89 if (!(schemeEntity.getEntityTypeId() instanceof String))
90 throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
91
92 try {
93 Map fields = EasyMap.build(SCHEME_ENTITY_SCHEME, scheme.getLong(SCHEME_ID),
94 SCHEME_ENTITY_LINKTYPE, schemeEntity.getType(),
95 SCHEME_ENTITY_SOURCE, schemeEntity.getParameter(),
96 SCHEME_ENTITY_DESTINATION, schemeEntity.getEntityTypeId().toString());
97 return EntityUtils.createValue(getEntityName(), fields);
98 } finally {
99 clearCache();
100 }
101 }
102
103 private void clearCache() {
104 if (log.isDebugEnabled())
105 log.debug("Clearing workflow scheme entity cache, had " + cache.size() + " entries");
106
107 cache.clear();
108 }
109
110
111
112
113 public List getLinkSchemeEntities(GenericValue scheme) throws GenericEntityException {
114 String cacheKey = createCacheKey(scheme, null);
115 List result = (List) cache.get(cacheKey);
116
117 if (result == null) {
118 result = scheme.getRelated("Child" + getEntityName());
119
120 if (result == null)
121 result = Collections.EMPTY_LIST;
122
123 if (log.isDebugEnabled())
124 log.debug("Caching " + result.size() + " entities for cache key: " + cacheKey);
125
126 cache.put(cacheKey, result);
127 }
128
129 return result;
130 }
131
132
133
134
135 public List toLinkSchemeEntityObjects(List _schemeEntities) {
136 List schemeEntities = new ArrayList();
137 for (Iterator iterator = _schemeEntities.iterator(); iterator.hasNext();) {
138 GenericValue gv = (GenericValue) iterator.next();
139 SchemeEntity schemeEntity = new LinkSchemeEntity(gv.getLong(SCHEME_ENTITY_ID), gv.getString(SCHEME_ENTITY_SOURCE), gv.getString(SCHEME_ENTITY_LINKTYPE), gv.getString(SCHEME_ENTITY_DESTINATION), gv.getLong(SCHEME_ENTITY_SCHEME));
140 schemeEntities.add(schemeEntity);
141 }
142 return schemeEntities;
143 }
144
145
146
147
148
149 public List getLinkSchemeEntities(GenericValue scheme, String sourceIssueTypeId) throws GenericEntityException {
150 String cacheKey = createCacheKey(scheme, sourceIssueTypeId);
151 List result = (List) cache.get(cacheKey);
152
153 if (result == null) {
154 result = scheme.getRelatedByAnd("Child" + getEntityName(), EasyMap.build(SCHEME_ENTITY_SOURCE, sourceIssueTypeId));
155
156 if (result == null)
157 result = Collections.EMPTY_LIST;
158
159 if (log.isDebugEnabled())
160 log.debug("Caching " + result.size() + " entities for cache key: " + cacheKey);
161
162 cache.put(cacheKey, result);
163 }
164
165 return result;
166 }
167
168 private String createCacheKey(GenericValue scheme, String sourceIssueTypeId) {
169 return scheme.getLong(SCHEME_ID) + "-" + sourceIssueTypeId;
170 }
171
172
173
174
175 public List getLinkSchemeEntities(GenericValue scheme, String sourceIssueTypeId, String linkTypeId, String destIssueTypeId) throws GenericEntityException {
176 String cacheKey = createCacheKey(scheme, sourceIssueTypeId, linkTypeId, destIssueTypeId);
177 List result = (List) cache.get(cacheKey);
178
179 if (result == null) {
180 result = scheme.getRelatedByAnd("Child" + getEntityName(), EasyMap.build(SCHEME_ENTITY_SOURCE, sourceIssueTypeId, SCHEME_ENTITY_LINKTYPE, linkTypeId, SCHEME_ENTITY_DESTINATION, destIssueTypeId));
181 if (result == null)
182 result = Collections.EMPTY_LIST;
183
184 if (log.isDebugEnabled())
185 log.debug("Caching " + result.size() + " entities for cache key: " + cacheKey);
186
187 cache.put(cacheKey, result);
188 }
189
190 return result;
191 }
192
193 private String createCacheKey(GenericValue scheme, String sourceIssueTypeId, String linkTypeId, String destIssueTypeId) {
194 return scheme.getLong(SCHEME_ID) + "-" + sourceIssueTypeId + "-" + linkTypeId + "-" + destIssueTypeId;
195 }
196
197
198
199
200 public List getEntities(GenericValue scheme, String sourceTypeId) throws GenericEntityException {
201 return getLinkSchemeEntities(scheme, sourceTypeId);
202 }
203
204
205
206
207 public List getEntities(GenericValue scheme, Long entityTypeId) throws GenericEntityException {
208 throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
209 }
210
211
212
213
214 public List getEntities(GenericValue scheme, Long entityTypeId, String parameter) throws GenericEntityException {
215 throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
216 }
217
218
219
220
221 public List getEntities(GenericValue scheme, String type, Long entityTypeId) throws GenericEntityException {
222 throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
223 }
224
225
226
227
228 public boolean hasSchemeAuthority(Long entityType, GenericValue entity) {
229 return false;
230 }
231
232
233
234
235 public boolean hasSchemeAuthority(Long entityType, GenericValue entity, User user, boolean issueCreation) {
236 return false;
237 }
238
239
240
241
242 public void addLinkToScheme(GenericValue scheme, String linkTypeId, String sourceIssueTypeId, String destIssueTypeId) throws GenericEntityException {
243 try {
244 SchemeEntity schemeEntity = new SchemeEntity(linkTypeId, sourceIssueTypeId, destIssueTypeId);
245
246
247 if (getLinkSchemeEntities(scheme, sourceIssueTypeId, linkTypeId, destIssueTypeId).size() == 0) {
248 createSchemeEntity(scheme, schemeEntity);
249 }
250 } finally {
251 clearCache();
252 }
253 }
254
255
256
257
258 public void deleteLinkToScheme(GenericValue scheme, String schemEntityId) throws GenericEntityException {
259 try {
260 GenericValue gvSchemeEntity = getLinkSchemeEntity(scheme, schemEntityId);
261 if (gvSchemeEntity!=null) {
262 gvSchemeEntity.remove();
263 }
264 } finally {
265 clearCache();
266 }
267 }
268
269
270
271
272 public GenericValue getLinkSchemeEntity(GenericValue scheme, String schemEntityId) throws GenericEntityException {
273 GenericValue gvSchemeEntity;
274 gvSchemeEntity = EntityUtil.getOnly(scheme.getRelatedByAnd("Child" + getEntityName(), EasyMap.build(SCHEME_ENTITY_ID, schemEntityId)));
275 return gvSchemeEntity;
276 }
277
278
279 }