View Javadoc
1   /**
2    * This file Copyright (c) 2015-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
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  
53  import org.apache.commons.lang3.StringUtils;
54  import org.slf4j.Logger;
55  import org.slf4j.LoggerFactory;
56  
57  import com.google.common.collect.ImmutableSet;
58  import com.vaadin.v7.data.Property;
59  import com.vaadin.v7.data.util.AbstractProperty;
60  
61  /**
62   * JCR implementation of {@link ThumbnailContainer} delegating to a {@link FlatJcrContainer}.
63   */
64  public class JcrThumbnailContainer extends FlatJcrContainer implements Refreshable, PagingThumbnailContainer {
65  
66      public static final String THUMBNAIL_PROPERTY_ID = "thumbnail";
67  
68      private static final Logger log = LoggerFactory.getLogger(JcrThumbnailContainer.class);
69  
70      private final ImageProvider imageProvider;
71  
72      public JcrThumbnailContainer(ImageProvider imageProvider, final JcrContentConnectorDefinition definition) {
73          super(definition);
74          this.imageProvider = imageProvider;
75      }
76  
77      // FILTERING OF JCR NODE-TYPES TO BE DISPLAYED AS THUMBNAILS
78  
79      @Override
80      protected String getQueryWhereClauseNodeTypes() {
81          List<String> defs = new ArrayList<>();
82          for (NodeTypeDefinition type : getConfiguration().getNodeTypes()) {
83              if (type.isHideInList() || NodeTypes.Folder.NAME.equals(type.getName())) {
84                  log.debug("Skipping {} node type. Nodes of such type won't be searched for.", type.getName());
85                  continue;
86              }
87              defs.add("[jcr:primaryType] = '" + type.getName() + "'");
88          }
89          return StringUtils.join(defs, " or ");
90      }
91  
92      @Override
93      public int indexOfId(Object itemId) {
94          if (!containsId(itemId)) {
95              return -1;
96          }
97          return super.indexOfId(itemId);
98      }
99  
100     @Override
101     public boolean containsId(Object itemId) {
102         final Item item = getJcrItem(itemId);
103         if (!item.isNode()) {
104             return super.containsId(itemId);
105         }
106 
107         Node node = (Node) item;
108         try {
109             if (!getConfiguration().isIncludeSystemNodes() && node.getName().startsWith("jcr:") || node.getName().startsWith("rep:")) {
110                 return false;
111             }
112 
113             String primaryNodeTypeName = node.getPrimaryNodeType().getName();
114             for (NodeTypeDefinition nodeTypeDefinition : getConfiguration().getNodeTypes()) {
115                 if (nodeTypeDefinition.isStrict()) {
116                     if (primaryNodeTypeName.equals(nodeTypeDefinition.getName())) {
117                         return true;
118                     }
119                 } else if (NodeUtil.isNodeType(node, nodeTypeDefinition.getName())) {
120                     return true;
121                 }
122             }
123 
124         } catch (RepositoryException e) {
125             log.error("Failed to check presence of {} in container", itemId, e);
126         }
127         return false;
128     }
129 
130     // SUPPORT OF THE THUMBNAIL CONTAINER PROPERTY
131 
132     @Override
133     public Collection<?> getContainerPropertyIds() {
134         return ImmutableSet.builder().addAll(super.getContainerPropertyIds()).add(THUMBNAIL_PROPERTY_ID).build();
135     }
136 
137     @Override
138     public Property getContainerProperty(Object itemId, Object propertyId) {
139         if (THUMBNAIL_PROPERTY_ID.equals(propertyId)) {
140             return new ThumbnailContainerProperty(itemId, imageProvider);
141         }
142         return super.getContainerProperty(itemId, propertyId);
143     }
144 
145     @Override
146     public Class<?> getType(Object propertyId) {
147         if (THUMBNAIL_PROPERTY_ID.equals(propertyId)) {
148             return Object.class;
149         }
150         return super.getType(propertyId);
151     }
152 
153     @Override
154     public Object getThumbnailPropertyId() {
155         return THUMBNAIL_PROPERTY_ID;
156     }
157 
158     @Override
159     public Property getThumbnailProperty(Object itemId) {
160         return getContainerProperty(itemId, THUMBNAIL_PROPERTY_ID);
161     }
162 
163     @Override
164     public void setPageSize(int pageSize) {
165         // TODO WHY 3?
166         int pageLength = Double.valueOf(Math.ceil(pageSize / 3.0)).intValue();
167         setPageLength(pageLength);
168         setCacheRatio(3);
169     }
170 
171     /**
172      * ThumbnailContainer property. Can have a Resource or a String as value.
173      */
174     public class ThumbnailContainerProperty extends AbstractProperty<Object> {
175 
176         private Object resourceId;
177 
178         private final ImageProvider imageProvider;
179 
180         public ThumbnailContainerProperty(final Object resourceId, ImageProvider imageProvider) {
181             this.resourceId = resourceId;
182             this.imageProvider = imageProvider;
183         }
184 
185         @Override
186         public Object getValue() {
187             if (imageProvider == null) {
188                 return null;
189             }
190             return imageProvider.getThumbnailResource(resourceId, ImageProvider.THUMBNAIL_GENERATOR);
191         }
192 
193         @Override
194         public void setValue(Object newValue) throws ReadOnlyException {
195             this.resourceId = newValue;
196         }
197 
198         @Override
199         public Class<Object> getType() {
200             return Object.class;
201         }
202     }
203 
204 }