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         try {
105             // In case of wrapped node like I18NWrapped content, we have to UnWrapp to get access to jcr:data property.
106             if (binaryNode instanceof DelegateNodeWrapper) {
107                binaryNode = ((DelegateNodeWrapper) binaryNode).deepUnwrap(I18nNodeWrapper.class);
108             }
109         } catch (RepositoryException e) {
110             throw new RuntimeException(e);
111         }
112 
113         return binaryNode;
114     }
115 
116     @Override
117     public boolean isExist() {
118         return getBinaryNode(false) != null;
119     }
120 
121     @Override
122     public InputStream getStream() {
123         if (isExist()) {
124             try {
125                 return getJCRProperty().getStream();
126             }
127             catch (RepositoryException e) {
128                 throw new RuntimeException("Can't read value of node data " + toString(), e);
129             }
130         }
131         return null;
132     }
133 
134     @Override
135     public void setValue(InputStream value) throws RepositoryException, AccessDeniedException {
136         getBinaryNode(true).setProperty(ItemType.JCR_DATA, value);
137     }
138 
139     @Override
140     public void delete() throws RepositoryException {
141         if(isExist()){
142             getBinaryNode(false).remove();
143         }
144     }
145 
146     @Override
147     public void setAttribute(String name, String value) throws RepositoryException, AccessDeniedException, UnsupportedOperationException {
148         getBinaryNode(true).setProperty(name, value);
149     }
150 
151     @Override
152     public void setAttribute(String name, Calendar value) throws RepositoryException, AccessDeniedException, UnsupportedOperationException {
153         getBinaryNode(true).setProperty(name, value);
154     }
155 
156     @Override
157     public String getAttribute(String name) {
158         if(isExist()){
159             Node binaryNode = getBinaryNode(false);
160             try {
161                 if(binaryNode.hasProperty(name)){
162                     return binaryNode.getProperty(name).getString();
163                 }
164             }
165             catch (RepositoryException e) {
166                 throw new IllegalStateException("Can't read attribute", e);
167             }
168         }
169         return "";
170     }
171 
172     @Override
173     public Collection<String> getAttributeNames() throws RepositoryException {
174         Collection<String> names = new ArrayList<String>();
175         if(isExist()){
176             PropertyIterator properties = getBinaryNode(false).getProperties();
177             while (properties.hasNext()) {
178                 String name = properties.nextProperty().getName();
179                 if (!name.equalsIgnoreCase(ItemType.JCR_DATA)) {
180                     names.add(name);
181                 }
182             }
183         }
184         return names;
185     }
186 
187     @Override
188     public int getType() {
189         return PropertyType.BINARY;
190     }
191 
192     @Override
193     public Value getValue() {
194         if(isExist()){
195             try {
196                 return getJCRProperty().getValue();
197             }
198             catch (RepositoryException e) {
199                 throw new IllegalStateException(e);
200             }
201         }
202         return null;
203     }
204 
205     @Override
206     public long getContentLength() {
207         if(!isExist()){
208             return 0;
209         }
210 
211         try {
212             return getJCRProperty().getLength();
213         }
214         catch (RepositoryException re) {
215             throw new RuntimeException(re);
216         }
217     }
218 
219     @Override
220     public int isMultiValue() {
221         return MULTIVALUE_FALSE;
222     }
223 
224     @Override
225     public void refresh(boolean keepChanges) throws RepositoryException {
226         if(isExist()){
227             getBinaryNode(false).refresh(keepChanges);
228         }
229     }
230 
231     @Override
232     public void save() throws RepositoryException {
233         if(isExist()){
234             getBinaryNode(false).save();
235         }
236     }
237 
238     @Override
239     public Content getReferencedContent() throws RepositoryException {
240         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
241     }
242 
243     @Override
244     public Content getReferencedContent(String repositoryId) throws RepositoryException {
245         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
246     }
247 
248     @Override
249     protected Content getContentFromJCRReference() throws RepositoryException {
250         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
251     }
252 
253     @Override
254     public String getString() {
255         if(isExist()){
256             try {
257                 return getJCRProperty().getString();
258             }
259             catch (RepositoryException e) {
260                 throw new RuntimeException("Can't read value of node data" + toString());
261             }
262         }
263         return "";
264     }
265 
266     @Override
267     public Calendar getDate() {
268         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
269     }
270 
271     @Override
272     public boolean getBoolean() {
273         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
274     }
275 
276     @Override
277     public double getDouble() {
278         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
279     }
280 
281     @Override
282     public long getLong() {
283         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
284     }
285 
286     @Override
287     public Value[] getValues() {
288         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
289     }
290 
291     @Override
292     public void setValue(String value) throws RepositoryException {
293         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
294     }
295 
296     @Override
297     public void setValue(int value) throws RepositoryException {
298         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
299     }
300 
301     @Override
302     public void setValue(long value) throws RepositoryException {
303         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
304     }
305 
306     @Override
307     public void setValue(double value) throws RepositoryException {
308         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
309     }
310 
311     @Override
312     public void setValue(boolean value) throws RepositoryException {
313         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
314     }
315 
316     @Override
317     public void setValue(Calendar value) throws RepositoryException {
318         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
319     }
320 
321     @Override
322     public void setValue(Content value) throws RepositoryException {
323         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
324     }
325 
326     @Override
327     public void setValue(Value value) throws RepositoryException {
328         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
329     }
330 
331     @Override
332     public void setValue(Value[] value) throws RepositoryException {
333         throw new UnsupportedOperationException("This operation is not supported on node datas of type BINARY");
334     }
335 }