Clover icon

Magnolia REST Services 1.1

  1. Project Clover database Thu Aug 13 2015 19:10:59 CEST
  2. Package info.magnolia.rest.service.node.v1

File RepositoryMarshaller.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

26
82
7
1
229
140
27
0.33
11.71
7
3.86

Classes

Class Line # Actions
RepositoryMarshaller 62 82 0% 27 4
0.965217496.5%
 

Contributing tests

This file is covered by 40 tests. .

Source view

1    /**
2    * This file Copyright (c) 2013-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.rest.service.node.v1;
35   
36    import info.magnolia.jcr.util.NodeTypes;
37    import info.magnolia.jcr.util.NodeUtil;
38    import info.magnolia.jcr.util.PropertyUtil;
39   
40    import java.io.ByteArrayInputStream;
41    import java.io.IOException;
42    import java.util.ArrayList;
43    import java.util.Collections;
44    import java.util.List;
45   
46    import javax.jcr.Node;
47    import javax.jcr.NodeIterator;
48    import javax.jcr.Property;
49    import javax.jcr.PropertyIterator;
50    import javax.jcr.PropertyType;
51    import javax.jcr.RepositoryException;
52    import javax.jcr.Value;
53    import javax.jcr.ValueFactory;
54   
55    import org.apache.commons.codec.binary.Base64;
56    import org.apache.commons.io.IOUtils;
57   
58    /**
59    * Marshaller used to marshall JCR content into its transfer representation {@link RepositoryNode} and unmarshall back
60    * into the repository.
61    */
 
62    public class RepositoryMarshaller {
63   
 
64  1 toggle public RepositoryNode marshallNode(final Node node) throws RepositoryException {
65  1 return marshallNode(node, 0, Collections.<String>emptyList(), true);
66    }
67   
 
68  15 toggle public RepositoryNode marshallNode(final Node node, int depth, final List<String> excludeNodeTypes, final boolean includeMeta) throws RepositoryException {
69   
70  15 RepositoryNode data = new RepositoryNode();
71  15 data.setName(node.getName());
72  15 data.setPath(node.getPath());
73  15 data.setIdentifier(node.getIdentifier());
74  15 data.setType(node.getPrimaryNodeType().getName());
75   
76  15 final PropertyIterator properties = node.getProperties();
77  38 while (properties.hasNext()) {
78  23 Property property = properties.nextProperty();
79  23 String propertyName = property.getName();
80   
81  23 if (!includeMeta && (propertyName.startsWith(NodeTypes.MGNL_PREFIX) || propertyName.startsWith(NodeTypes.JCR_PREFIX))) {
82  2 continue;
83    }
84   
85  21 data.getProperties().add(marshallProperty(property));
86    }
87   
88  15 if (depth > 0) {
89  3 final NodeIterator nodes = node.getNodes();
90  7 while (nodes.hasNext()) {
91  4 Node child = nodes.nextNode();
92  4 if (excludeNodeTypes == null || (!excludeNodeTypes.contains(child.getPrimaryNodeType().getName()))) {
93  3 data.addNode(marshallNode(child, --depth, excludeNodeTypes, includeMeta));
94    }
95    }
96    }
97   
98  15 return data;
99    }
100   
 
101  23 toggle public RepositoryProperty marshallProperty(Property property) throws RepositoryException {
102   
103  23 RepositoryProperty data = new RepositoryProperty();
104  23 data.setName(property.getName());
105  23 data.setType(PropertyType.nameFromValue(property.getType()));
106  23 data.setMultiple(property.isMultiple());
107   
108  23 List<String> values = new ArrayList<String>();
109  23 if (property.isMultiple()) {
110  5 for (Value propertyValue : property.getValues()) {
111  11 values.add(getStringByValue(propertyValue));
112    }
113    } else {
114  18 values.add(getStringByValue(property.getValue()));
115    }
116  23 data.setValues(values);
117   
118  23 return data;
119    }
120   
 
121  13 toggle public void unmarshallProperties(final Node node, List<RepositoryProperty> properties) throws RepositoryException {
122  13 for (RepositoryProperty property : properties) {
123  10 unmarshallProperty(node, property);
124    }
125    }
126   
 
127  18 toggle public void unmarshallProperty(Node node, RepositoryProperty property) throws RepositoryException {
128   
129  18 ValueFactory valueFactory = node.getSession().getValueFactory();
130   
131  18 if (property.isMultiple()) {
132   
133    // Multi-valued property
134   
135  4 Value[] values;
136  4 if (property.getValues() != null) {
137  4 values = new Value[property.getValues().size()];
138  4 int propertyType = PropertyType.valueFromName(property.getType());
139  4 int i = 0;
140  4 for (String propertyValue : property.getValues()) {
141  7 values[i++] = getValueByType(propertyType, propertyValue, valueFactory);
142    }
143    } else {
144  0 values = new Value[0];
145    }
146   
147  4 String name = property.getName();
148  4 if (node.hasProperty(name)) {
149  1 Property existingProperty = node.getProperty(name);
150  1 if (!existingProperty.isMultiple()) {
151  1 existingProperty.remove();
152    }
153    }
154   
155  4 node.setProperty(property.getName(), values);
156   
157    } else {
158   
159    // Single-valued property
160   
161  14 if (property.getValues() == null || property.getValues().size() != 1) {
162  2 throw new IllegalArgumentException("Cannot set more than one value unless the property is multi-valued, [" + property.getName() + "] on [" + NodeUtil.getNodePathIfPossible(node) + "]");
163    }
164   
165  12 final int propertyType = PropertyType.valueFromName(property.getType());
166  12 final String propertyValue = property.getValues().get(0);
167  12 Value value = getValueByType(propertyType, propertyValue, valueFactory);
168   
169  12 String name = property.getName();
170  12 if (node.hasProperty(name)) {
171  3 Property existingProperty = node.getProperty(name);
172  3 if (existingProperty.isMultiple()) {
173  1 existingProperty.remove();
174    }
175    }
176   
177  12 node.setProperty(property.getName(), value);
178    }
179    }
180   
181    /**
182    * Gets a string representation of a {@link javax.jcr.Value}.
183    * {@link PropertyType#BINARY} types will be base64 encoded.
184    * @see org.apache.commons.codec.binary.Base64#encode(byte[])
185    */
 
186  31 toggle protected String getStringByValue(final Value propertyValue) throws RepositoryException {
187  31 String value;
188  31 final int propertyType = propertyValue.getType();
189   
190  31 switch (propertyType) {
191  1 case PropertyType.BINARY:
192    // Binary values have to be base64 encoded
193  1 byte[] decodedPropertyValue;
194  1 try {
195  1 decodedPropertyValue = Base64.encodeBase64(IOUtils.toByteArray(propertyValue.getBinary().getStream()));
196    } catch (IOException e) {
197  0 throw new RepositoryException(e);
198    }
199  1 value = new String(decodedPropertyValue);
200  1 break;
201  30 default:
202  30 value = propertyValue.getString();
203    }
204   
205  31 return value;
206    }
207   
208    /**
209    * Get the {@link javax.jcr.Value} of a property value according to its type.
210    * Converting {@link PropertyType#BINARY} types requires the String to be base64 encoded.
211    * @see org.apache.commons.codec.binary.Base64#decodeBase64(String)
212    */
 
213  24 toggle protected Value getValueByType(final int propertyType, final String propertyValue, final ValueFactory valueFactory) throws RepositoryException {
214  24 Value value;
215   
216  24 switch (propertyType) {
217  1 case PropertyType.BINARY:
218    // We expect binary values to be base64 encoded
219  1 byte[] decodedPropertyValue = Base64.decodeBase64(propertyValue);
220  1 value = PropertyUtil.createValue(new ByteArrayInputStream(decodedPropertyValue), valueFactory);
221  1 break;
222  23 default:
223  23 value = PropertyUtil.createValue(propertyValue, propertyType, valueFactory);
224    }
225   
226  24 return value;
227    }
228   
229    }