View Javadoc

1   /**
2    * This file Copyright (c) 2010-2011 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.wrapper.DelegateNodeWrapper;
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   * @author pbaerfuss
55   * @version $Id$
56   */
57  public class BinaryNodeData extends AbstractNodeData {
58  
59      /**
60       * The node containing the binary and attributes.
61       */
62      private Node binaryNode;
63  
64      /**
65       * The property containing the binary.
66       * @see ItemType.JCR_DATA
67       */
68      private Property binaryProperty;
69  
70      protected BinaryNodeData(Content parent, String name) {
71          super(parent, name);
72      }
73  
74      @Override
75      public Property getJCRProperty() {
76          if(binaryProperty == null){
77              if(isExist()){
78                  try {
79                      binaryProperty = getBinaryNode(false).getProperty(ItemType.JCR_DATA);
80                  }
81                  catch (RepositoryException e) {
82                      throw new IllegalStateException(e);
83                  }
84              }
85          }
86          return binaryProperty;
87      }
88  
89      protected Node getBinaryNode(boolean createIfNotExisting) {
90          if(binaryNode == null){
91              Node parentJCRNode = getParent().getJCRNode();
92              try {
93                  if(parentJCRNode.hasNode(name)){
94                      binaryNode = parentJCRNode.getNode(name);
95                  }
96                  else if(createIfNotExisting){
97                      binaryNode = parentJCRNode.addNode(name, ItemType.NT_RESOURCE);
98                  }
99              }
100             catch (RepositoryException e) {
101                 throw new RuntimeException(e);
102             }
103         }
104         // In case of wrapped node like I18NWrapped content, we have to UnWrapp to get access to jcr:data property.
105         if (binaryNode instanceof DelegateNodeWrapper) {
106            binaryNode = ((DelegateNodeWrapper) binaryNode).deepUnwrap(I18nNodeWrapper.class);
107         }
108 
109         return binaryNode;
110     }
111 
112     @Override
113     public boolean isExist() {
114         return getBinaryNode(false) != null;
115     }
116 
117     @Override
118     public InputStream getStream() {
119         if (isExist()) {
120             try {
121                 return getJCRProperty().getStream();
122             }
123             catch (RepositoryException e) {
124                 throw new RuntimeException("Can't read value of node data " + toString(), e);
125             }
126         }
127         return null;
128     }
129 
130     @Override
131     public void setValue(InputStream value) throws RepositoryException, AccessDeniedException {
132         getBinaryNode(true).setProperty(ItemType.JCR_DATA, value);
133     }
134 
135     @Override
136     public void delete() throws RepositoryException {
137         if(isExist()){
138             getBinaryNode(false).remove();
139         }
140     }
141 
142     @Override
143     public void setAttribute(String name, String value) throws RepositoryException, AccessDeniedException, UnsupportedOperationException {
144         getBinaryNode(true).setProperty(name, value);
145     }
146 
147     @Override
148     public void setAttribute(String name, Calendar value) throws RepositoryException, AccessDeniedException, UnsupportedOperationException {
149         getBinaryNode(true).setProperty(name, value);
150     }
151 
152     @Override
153     public String getAttribute(String name) {
154         if(isExist()){
155             Node binaryNode = getBinaryNode(false);
156             try {
157                 if(binaryNode.hasProperty(name)){
158                     return binaryNode.getProperty(name).getString();
159                 }
160             }
161             catch (RepositoryException e) {
162                 throw new IllegalStateException("Can't read attribute", e);
163             }
164         }
165         return "";
166     }
167 
168     @Override
169     public Collection<String> getAttributeNames() throws RepositoryException {
170         Collection<String> names = new ArrayList<String>();
171         if(isExist()){
172             PropertyIterator properties = getBinaryNode(false).getProperties();
173             while (properties.hasNext()) {
174                 String name = properties.nextProperty().getName();
175                 if (!name.equalsIgnoreCase(ItemType.JCR_DATA)) {
176                     names.add(name);
177                 }
178             }
179         }
180         return names;
181     }
182 
183     @Override
184     public int getType() {
185         return PropertyType.BINARY;
186     }
187 
188     @Override
189     public Value getValue() {
190         if(isExist()){
191             try {
192                 return getJCRProperty().getValue();
193             }
194             catch (RepositoryException e) {
195                 throw new IllegalStateException(e);
196             }
197         }
198         return null;
199     }
200 
201     @Override
202     public long getContentLength() {
203         if(!isExist()){
204             return 0;
205         }
206 
207         try {
208             return getJCRProperty().getLength();
209         }
210         catch (RepositoryException re) {
211             throw new RuntimeException(re);
212         }
213     }
214 
215     @Override
216     public int isMultiValue() {
217         return MULTIVALUE_FALSE;
218     }
219 
220     @Override
221     public void refresh(boolean keepChanges) throws RepositoryException {
222         if(isExist()){
223             getBinaryNode(false).refresh(keepChanges);
224         }
225     }
226 
227     @Override
228     public void save() throws RepositoryException {
229         if(isExist()){
230             getBinaryNode(false).save();
231         }
232     }
233 
234     @Override
235     public Content getReferencedContent() throws RepositoryException {
236         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
237     }
238 
239     @Override
240     public Content getReferencedContent(String repositoryId) throws RepositoryException {
241         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
242     }
243 
244     @Override
245     protected Content getContentFromJCRReference() throws RepositoryException {
246         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
247     }
248 
249     @Override
250     public String getString() {
251         if(isExist()){
252             try {
253                 return getJCRProperty().getString();
254             }
255             catch (RepositoryException e) {
256                 throw new RuntimeException("Can't read value of node data" + toString());
257             }
258         }
259         return "";
260     }
261 
262     @Override
263     public Calendar getDate() {
264         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
265     }
266 
267     @Override
268     public boolean getBoolean() {
269         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
270     }
271 
272     @Override
273     public double getDouble() {
274         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
275     }
276 
277     @Override
278     public long getLong() {
279         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
280     }
281 
282     @Override
283     public Value[] getValues() {
284         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
285     }
286 
287     @Override
288     public void setValue(String 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(int 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(long 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(double 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(boolean 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(Calendar 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(Content value) throws RepositoryException {
319         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
320     }
321 
322     @Override
323     public void setValue(Value value) throws RepositoryException {
324         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
325     }
326 
327     @Override
328     public void setValue(Value[] value) throws RepositoryException {
329         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
330     }
331 }