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