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