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.ui.workbench.thumbnail;
35
36 import info.magnolia.jcr.util.NodeTypes;
37 import info.magnolia.jcr.util.NodeUtil;
38 import info.magnolia.ui.imageprovider.ImageProvider;
39 import info.magnolia.ui.vaadin.integration.contentconnector.JcrContentConnectorDefinition;
40 import info.magnolia.ui.vaadin.integration.contentconnector.NodeTypeDefinition;
41 import info.magnolia.ui.vaadin.layout.data.PagingThumbnailContainer;
42 import info.magnolia.ui.workbench.container.Refreshable;
43 import info.magnolia.ui.workbench.list.FlatJcrContainer;
44
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.List;
48
49 import javax.jcr.Item;
50 import javax.jcr.Node;
51 import javax.jcr.RepositoryException;
52 import javax.jcr.Session;
53
54 import org.apache.commons.lang3.StringUtils;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 import com.google.common.collect.ImmutableSet;
59 import com.vaadin.v7.data.Property;
60 import com.vaadin.v7.data.util.AbstractProperty;
61
62
63
64
65 public class JcrThumbnailContainer extends FlatJcrContainer implements Refreshable, PagingThumbnailContainer {
66
67 public static final String THUMBNAIL_PROPERTY_ID = "thumbnail";
68
69 private static final Logger log = LoggerFactory.getLogger(JcrThumbnailContainer.class);
70
71 private final ImageProvider imageProvider;
72
73 public JcrThumbnailContainer(ImageProvider imageProvider, final JcrContentConnectorDefinition definition) {
74 super(definition);
75 this.imageProvider = imageProvider;
76 }
77
78
79
80 @Override
81 protected String getQueryWhereClauseNodeTypes() {
82 List<String> defs = new ArrayList<>();
83 for (NodeTypeDefinition type : getConfiguration().getNodeTypes()) {
84 if (type.isHideInList() || NodeTypes.Folder.NAME.equals(type.getName())) {
85 log.debug("Skipping {} node type. Nodes of such type won't be searched for.", type.getName());
86 continue;
87 }
88 defs.add("[jcr:primaryType] = '" + type.getName() + "'");
89 }
90 return StringUtils.join(defs, " or ");
91 }
92
93 @Override
94 public int indexOfId(Object itemId) {
95 if (!containsId(itemId)) {
96 return -1;
97 }
98 return super.indexOfId(itemId);
99 }
100
101 @Override
102 public boolean containsId(Object itemId) {
103 final Item item = getJcrItem(itemId);
104 if (!item.isNode()) {
105 return super.containsId(itemId);
106 }
107
108 Node node = (Node) item;
109 try {
110 if (!getConfiguration().isIncludeSystemNodes() && node.getName().startsWith("jcr:") || node.getName().startsWith("rep:")) {
111 return false;
112 }
113
114 String primaryNodeTypeName = node.getPrimaryNodeType().getName();
115 for (NodeTypeDefinition nodeTypeDefinition : getConfiguration().getNodeTypes()) {
116 if (nodeTypeDefinition.isStrict()) {
117 if (primaryNodeTypeName.equals(nodeTypeDefinition.getName())) {
118 return true;
119 }
120 } else if (NodeUtil.isNodeType(node, nodeTypeDefinition.getName())) {
121 return true;
122 }
123 }
124
125 } catch (RepositoryException e) {
126 log.error("Failed to check presence of {} in container", itemId, e);
127 }
128 return false;
129 }
130
131
132
133 @Override
134 public Collection<?> getContainerPropertyIds() {
135 return ImmutableSet.builder().addAll(super.getContainerPropertyIds()).add(THUMBNAIL_PROPERTY_ID).build();
136 }
137
138 @Override
139 public Property getContainerProperty(Object itemId, Object propertyId) {
140 if (THUMBNAIL_PROPERTY_ID.equals(propertyId)) {
141 return new ThumbnailContainerProperty(itemId, imageProvider);
142 }
143 return super.getContainerProperty(itemId, propertyId);
144 }
145
146 @Override
147 public Class<?> getType(Object propertyId) {
148 if (THUMBNAIL_PROPERTY_ID.equals(propertyId)) {
149 return Object.class;
150 }
151 return super.getType(propertyId);
152 }
153
154 @Override
155 public Object getThumbnailPropertyId() {
156 return THUMBNAIL_PROPERTY_ID;
157 }
158
159 @Override
160 public Property getThumbnailProperty(Object itemId) {
161 return getContainerProperty(itemId, THUMBNAIL_PROPERTY_ID);
162 }
163
164 @Override
165 public Property getCaptionProperty(Object itemId) {
166 return new ThumbnailCaptionProperty(itemId);
167 }
168
169 @Override
170 public void setPageSize(int pageSize) {
171
172 int pageLength = Double.valueOf(Math.ceil(pageSize / 3.0)).intValue();
173 setPageLength(pageLength);
174 setCacheRatio(3);
175 }
176
177
178
179
180 public class ThumbnailContainerProperty extends AbstractProperty<Object> {
181
182 private Object resourceId;
183
184 private final ImageProvider imageProvider;
185
186 public ThumbnailContainerProperty(final Object resourceId, ImageProvider imageProvider) {
187 this.resourceId = resourceId;
188 this.imageProvider = imageProvider;
189 }
190
191 @Override
192 public Object getValue() {
193 if (imageProvider == null) {
194 return null;
195 }
196 return imageProvider.getThumbnailResource(resourceId, ImageProvider.THUMBNAIL_GENERATOR);
197 }
198
199 @Override
200 public void setValue(Object newValue) throws ReadOnlyException {
201 this.resourceId = newValue;
202 }
203
204 @Override
205 public Class<Object> getType() {
206 return Object.class;
207 }
208 }
209
210
211
212
213 public class ThumbnailCaptionProperty extends AbstractProperty<Object> {
214
215 private Object resourceId;
216
217 public ThumbnailCaptionProperty(final Object resourceId) {
218 this.resourceId = resourceId;
219 }
220
221 @Override
222 public Object getValue() {
223 try {
224 Session session = getJcrItem(resourceId).getSession();
225 Node thumbnail = session.getNode(String.format("%s/%s", getJcrItem(resourceId).getPath(), THUMBNAIL_PROPERTY_ID));
226 String fileName = thumbnail.getProperty("fileName").getString();
227 String extension = thumbnail.getProperty("extension").getString();
228 return String.format("%s.%s", fileName, extension);
229 } catch (RepositoryException e) {
230 log.debug("The caption for the thumbnail '%s' couldn't be built, returning the raw node name instead.", resourceId, e);
231 }
232
233 try {
234 return getJcrItem(resourceId).getName();
235 } catch (RepositoryException e) {
236 log.debug("The node name for '%s' couldn't be fetched either, returning an empty string.", resourceId, e);
237 }
238
239 return "";
240 }
241
242 @Override
243 public void setValue(Object newValue) throws ReadOnlyException {
244 this.resourceId = newValue;
245 }
246
247 @Override
248 public Class<Object> getType() {
249 return Object.class;
250 }
251 }
252
253 }