View Javadoc
1   /**
2    * This file Copyright (c) 2010-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.cms.core;
35  
36  import info.magnolia.cms.security.AccessDeniedException;
37  import info.magnolia.jcr.util.NodeUtil;
38  import info.magnolia.jcr.wrapper.I18nNodeWrapper;
39  
40  import java.io.InputStream;
41  import java.util.ArrayList;
42  import java.util.Calendar;
43  import java.util.Collection;
44  
45  import javax.jcr.Node;
46  import javax.jcr.Property;
47  import javax.jcr.PropertyIterator;
48  import javax.jcr.PropertyType;
49  import javax.jcr.RepositoryException;
50  import javax.jcr.Value;
51  
52  /**
53   * A node data hiding the fact that node datas of type BINARY are stored as nodes of type {@link ItemType#NT_RESOURCE}.
54   */
55  public class BinaryNodeData extends AbstractNodeData {
56  
57      /**
58       * The node containing the binary and attributes.
59       */
60      private Node binaryNode;
61  
62      /**
63       * The property containing the binary.
64       *
65       * @see ItemType.JCR_DATA
66       */
67      private Property binaryProperty;
68  
69      protected BinaryNodeData(Content parent, String name) {
70          super(parent, name);
71      }
72  
73      @Override
74      public Property getJCRProperty() {
75          if (binaryProperty == null) {
76              if (isExist()) {
77                  try {
78                      binaryProperty = getBinaryNode(false).getProperty(ItemType.JCR_DATA);
79                  } catch (RepositoryException e) {
80                      throw new IllegalStateException(e);
81                  }
82              }
83          }
84          return binaryProperty;
85      }
86  
87      protected Node getBinaryNode(boolean createIfNotExisting) {
88          if (binaryNode == null) {
89              Node parentJCRNode = getParent().getJCRNode();
90  
91              try {
92                  if (parentJCRNode.hasNode(name)) {
93                      binaryNode = parentJCRNode.getNode(name);
94                  } else if (createIfNotExisting) {
95                      binaryNode = parentJCRNode.addNode(name, ItemType.NT_RESOURCE);
96                  }
97  
98                  binaryNode = NodeUtil.deepUnwrapAll(binaryNode, I18nNodeWrapper.class);
99  
100             } catch (RepositoryException e) {
101                 throw new RuntimeException(e);
102             }
103         }
104         return binaryNode;
105     }
106 
107     @Override
108     public boolean isExist() {
109         return getBinaryNode(false) != null;
110     }
111 
112     @Override
113     public InputStream getStream() {
114         if (isExist()) {
115             try {
116                 return getJCRProperty().getStream();
117             } catch (RepositoryException e) {
118                 throw new RuntimeException("Can't read value of node data " + toString(), e);
119             }
120         }
121         return null;
122     }
123 
124     @Override
125     public void setValue(InputStream value) throws RepositoryException, AccessDeniedException {
126         getBinaryNode(true).setProperty(ItemType.JCR_DATA, value);
127     }
128 
129     @Override
130     public void delete() throws RepositoryException {
131         if (isExist()) {
132             getBinaryNode(false).remove();
133         }
134     }
135 
136     @Override
137     public void setAttribute(String name, String value) throws RepositoryException, AccessDeniedException, UnsupportedOperationException {
138         getBinaryNode(true).setProperty(name, value);
139     }
140 
141     @Override
142     public void setAttribute(String name, Calendar value) throws RepositoryException, AccessDeniedException, UnsupportedOperationException {
143         getBinaryNode(true).setProperty(name, value);
144     }
145 
146     @Override
147     public String getAttribute(String name) {
148         if (isExist()) {
149             Node binaryNode = getBinaryNode(false);
150             try {
151                 if (binaryNode.hasProperty(name)) {
152                     return binaryNode.getProperty(name).getString();
153                 }
154             } catch (RepositoryException e) {
155                 throw new IllegalStateException("Can't read attribute", e);
156             }
157         }
158         return "";
159     }
160 
161     @Override
162     public Collection<String> getAttributeNames() throws RepositoryException {
163         Collection<String> names = new ArrayList<String>();
164         if (isExist()) {
165             PropertyIterator properties = getBinaryNode(false).getProperties();
166             while (properties.hasNext()) {
167                 String name = properties.nextProperty().getName();
168                 if (!name.equalsIgnoreCase(ItemType.JCR_DATA)) {
169                     names.add(name);
170                 }
171             }
172         }
173         return names;
174     }
175 
176     @Override
177     public int getType() {
178         return PropertyType.BINARY;
179     }
180 
181     @Override
182     public Value getValue() {
183         if (isExist()) {
184             try {
185                 return getJCRProperty().getValue();
186             } catch (RepositoryException e) {
187                 throw new IllegalStateException(e);
188             }
189         }
190         return null;
191     }
192 
193     @Override
194     public long getContentLength() {
195         if (!isExist()) {
196             return 0;
197         }
198 
199         try {
200             return getJCRProperty().getLength();
201         } catch (RepositoryException re) {
202             throw new RuntimeException(re);
203         }
204     }
205 
206     @Override
207     public int isMultiValue() {
208         return MULTIVALUE_FALSE;
209     }
210 
211     @Override
212     public void refresh(boolean keepChanges) throws RepositoryException {
213         if (isExist()) {
214             getBinaryNode(false).refresh(keepChanges);
215         }
216     }
217 
218     @Override
219     public void save() throws RepositoryException {
220         if (isExist()) {
221             getBinaryNode(false).save();
222         }
223     }
224 
225     @Override
226     public Content getReferencedContent() throws RepositoryException {
227         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
228     }
229 
230     @Override
231     public Content getReferencedContent(String repositoryId) throws RepositoryException {
232         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
233     }
234 
235     @Override
236     protected Content getContentFromJCRReference() throws RepositoryException {
237         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
238     }
239 
240     @Override
241     public String getString() {
242         if (isExist()) {
243             try {
244                 return getJCRProperty().getString();
245             } catch (RepositoryException e) {
246                 throw new RuntimeException("Can't read value of node data" + toString());
247             }
248         }
249         return "";
250     }
251 
252     @Override
253     public Calendar getDate() {
254         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
255     }
256 
257     @Override
258     public boolean getBoolean() {
259         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
260     }
261 
262     @Override
263     public double getDouble() {
264         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
265     }
266 
267     @Override
268     public long getLong() {
269         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
270     }
271 
272     @Override
273     public Value[] getValues() {
274         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
275     }
276 
277     @Override
278     public void setValue(String value) throws RepositoryException {
279         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
280     }
281 
282     @Override
283     public void setValue(int value) throws RepositoryException {
284         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
285     }
286 
287     @Override
288     public void setValue(long value) throws RepositoryException {
289         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
290     }
291 
292     @Override
293     public void setValue(double value) throws RepositoryException {
294         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
295     }
296 
297     @Override
298     public void setValue(boolean value) throws RepositoryException {
299         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
300     }
301 
302     @Override
303     public void setValue(Calendar value) throws RepositoryException {
304         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
305     }
306 
307     @Override
308     public void setValue(Content value) throws RepositoryException {
309         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
310     }
311 
312     @Override
313     public void setValue(Value value) throws RepositoryException {
314         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
315     }
316 
317     @Override
318     public void setValue(Value[] value) throws RepositoryException {
319         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
320     }
321 }