1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.rssaggregator.util;
35
36 import static java.util.Collections.emptyList;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.search.Query;
39 import info.magnolia.cms.util.QueryUtil;
40
41 import java.util.ArrayList;
42 import java.util.Collection;
43 import java.util.List;
44
45 import javax.jcr.Node;
46 import javax.jcr.RepositoryException;
47
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52
53
54
55
56
57
58 public class MagnoliaTemplate implements MagnoliaQueryOperations {
59
60
61 protected Logger logger = LoggerFactory.getLogger(getClass());
62
63
64 public <T> List<T> queryForList(String repository, String query, String language, String type, ContentMapper<T> mapper) {
65 return query(repository, query, language, type, mapper);
66 }
67
68
69 public <T> T queryForObject(String repository, String query, String language, String type, ContentMapper<T> mapper) {
70 List<T> results = query(repository, query, language, type, mapper);
71 return singleResult(results);
72 }
73
74
75 public <T> List<T> xpathQueryForList(String repository, String query, String type, ContentMapper<T> mapper) throws DataAccessException {
76 return queryForList(repository, query, Query.XPATH, type, mapper);
77 }
78
79
80 public <T> T xpathQueryForObject(String repository, String query, String type, ContentMapper<T> mapper) throws DataAccessException {
81 return queryForObject(repository, query, Query.XPATH, type, mapper);
82 }
83
84
85 public Node xpathQueryForContent(String repository, String query, String type) throws DataAccessException {
86 return queryForObject(repository, query, Query.XPATH, type, new ContentMapper<Node>() {
87 public Node map(Node content) throws RepositoryException {
88 return content;
89 }
90 });
91 }
92
93
94
95 protected <T> List<T> query(String repository, String query, String language, String type, ContentMapper<T> mapper) throws DataAccessException {
96 Collection<Content> contents = queryInternal(repository, query, language, type);
97 if (contents.isEmpty()) {
98 return emptyList();
99 }
100 List<T> result = new ArrayList<T>(contents.size());
101 for (Content content : contents) {
102 try {
103 result.add(mapper.map(content.getJCRNode()));
104 } catch (RepositoryException re) {
105 throw new DataAccessException(String.format("Failed to map content '%s' using mapper '%s'", content, mapper.getClass()));
106 }
107 }
108 return result;
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 protected <T> Collection<T> queryInternal(String repository, String query, String language, String type) {
127 try {
128 return doExceptionThrowingQuery(repository, query, language, type);
129 } catch (RepositoryException re) {
130 throw new DataAccessException("A repository exception occurred", re);
131
132 }
133 }
134
135 @SuppressWarnings("unchecked")
136 protected <T> Collection<T> doExceptionThrowingQuery(String repository, String query, String language, String type) throws RepositoryException {
137 logger.debug("Executing {} query for '{}' in repository '{}': \"{}\"", new Object[] {language,
138 type, repository, query}
139 );
140 Collection<T> results = (Collection<T>) QueryUtil.exceptionThrowingQuery(repository, query, language, type);
141 logger.debug("Query returned %s result(s)", (results == null) ? null : results.size());
142 return results;
143 }
144
145
146
147
148
149
150
151
152
153 protected static <T> T singleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {
154 int size = (results == null ? 0 : results.size());
155 if (size == 0) {
156 return null;
157 }
158 if (results.size() > 1) {
159 throw new IncorrectResultSizeDataAccessException(1, size);
160 }
161 return results.iterator().next();
162 }
163
164 }