| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.sling.jcr.resource.internal.helper; |
| |
| import com.google.common.collect.Maps; |
| import org.apache.jackrabbit.value.BooleanValue; |
| import org.apache.jackrabbit.value.ValueFactoryImpl; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import javax.jcr.Node; |
| import javax.jcr.Property; |
| import javax.jcr.PropertyType; |
| import javax.jcr.RepositoryException; |
| import javax.jcr.Session; |
| import javax.jcr.Value; |
| import javax.jcr.ValueFactory; |
| import javax.jcr.ValueFormatException; |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.InputStream; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.util.Calendar; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.verifyNoMoreInteractions; |
| import static org.mockito.Mockito.verifyZeroInteractions; |
| import static org.mockito.Mockito.when; |
| |
| /** |
| * Testcase for {@link JcrPropertyMapCacheEntry} |
| */ |
| public class JcrPropertyMapCacheEntryTest { |
| |
| private final ValueFactory vf = ValueFactoryImpl.getInstance(); |
| private final Session session = mock(Session.class); |
| private final Node node = mock(Node.class); |
| |
| @Before |
| public void before() throws Exception { |
| when(session.getValueFactory()).thenReturn(vf); |
| when(node.getSession()).thenReturn(session); |
| } |
| |
| @Test |
| public void testByteArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Byte[0], node); |
| new JcrPropertyMapCacheEntry(new byte[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testShortArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Short[0], node); |
| new JcrPropertyMapCacheEntry(new short[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testIntArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Integer[0], node); |
| new JcrPropertyMapCacheEntry(new int[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testLongArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Long[0], node); |
| new JcrPropertyMapCacheEntry(new long[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testFloatArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Float[0], node); |
| new JcrPropertyMapCacheEntry(new float[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testDoubleArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Double[0], node); |
| new JcrPropertyMapCacheEntry(new double[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testBooleanArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Boolean[0], node); |
| new JcrPropertyMapCacheEntry(new boolean[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testCharArray() throws Exception { |
| new JcrPropertyMapCacheEntry(new Character[0], node); |
| new JcrPropertyMapCacheEntry(new char[0], node); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testCannotStore() throws Exception { |
| Object value = new TestClass(); |
| new JcrPropertyMapCacheEntry(value, node); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testCannotStoreArray() throws Exception { |
| Object value = new TestClass(); |
| new JcrPropertyMapCacheEntry(new Object[] {value}, node); |
| } |
| |
| @Test |
| public void testGetPropertyValueOrNull() throws Exception { |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(true, node); |
| assertEquals(Boolean.TRUE, entry.getPropertyValueOrNull()); |
| } |
| |
| @Test |
| public void testGetPropertyValueOrNullWithRepositoryException() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.BINARY); |
| when(prop.getValue()).thenThrow(new RepositoryException()); |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| assertNull(entry.getPropertyValueOrNull()); |
| } |
| |
| @Test |
| public void testInputStreamToString() throws Exception { |
| InputStream in = new ByteArrayInputStream("test".getBytes()); |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(in, node); |
| |
| String result = entry.convertToType(String.class, node, null); |
| assertEquals("test", result); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testInputStreamToLong() throws Exception { |
| InputStream in = new ByteArrayInputStream("10".getBytes()); |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(in, node); |
| |
| Long result = entry.convertToType(Long.class, node, null); |
| assertNull(result); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testInputStreamToIntegerArray() throws Exception { |
| InputStream in = new ByteArrayInputStream("10".getBytes()); |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(in, node); |
| |
| Integer[] result = entry.convertToType(Integer[].class, node, null); |
| assertNotNull(result); |
| assertEquals(0, result.length); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testBinaryPropertyToInteger() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.BINARY); |
| when(prop.getStream()).thenReturn(new ByteArrayInputStream("10".getBytes())); |
| when(prop.getValue()).thenReturn(vf.createValue(new ByteArrayInputStream("10".getBytes()))); |
| when(prop.getLength()).thenReturn(2L); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| Integer result = entry.convertToType(Integer.class, node, null); |
| assertEquals(Integer.valueOf(2), result); |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValue(); |
| verify(prop).getType(); |
| verify(prop).getLength(); |
| verifyNoMoreInteractions(prop); |
| |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testBinaryPropertyToDoubleArray() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.BINARY); |
| when(prop.getStream()).thenReturn(new ByteArrayInputStream("10.7".getBytes())); |
| when(prop.getValue()).thenReturn(vf.createValue(new ByteArrayInputStream("10.7".getBytes()))); |
| when(prop.getLength()).thenReturn(4L); |
| when(prop.getLengths()).thenThrow(new ValueFormatException("single-valued")); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| Double[] result = entry.convertToType(Double[].class, node, null); |
| assertNotNull(result); |
| assertEquals(1, result.length); |
| assertEquals(Double.valueOf(4.0), result[0]); |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValue(); |
| verify(prop).getType(); |
| verify(prop).getLength(); |
| verifyNoMoreInteractions(prop); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testMvBinaryPropertyToFloatArray() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.BINARY); |
| when(prop.isMultiple()).thenReturn(true); |
| when(prop.getValue()).thenThrow(new ValueFormatException("multi-valued")); |
| Value[] vs = new Value[] {vf.createValue("10.7", PropertyType.BINARY), vf.createValue("10.7", PropertyType.BINARY)}; |
| when(prop.getValues()).thenReturn(vs); |
| when(prop.getLength()).thenThrow(new ValueFormatException("multi-valued")); |
| when(prop.getLengths()).thenReturn(new long[] {4L, 4L}); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| Float[] result = entry.convertToType(Float[].class, node, null); |
| assertNotNull(result); |
| assertEquals(2, result.length); |
| assertEquals(Float.valueOf(4.0f), result[0]); |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValues(); |
| verify(prop).getType(); |
| verify(prop, times(2)).getLengths(); |
| verifyNoMoreInteractions(prop); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testInputStreamToObjectInputStream() throws Exception { |
| InputStream in = new ByteArrayInputStream("value".getBytes()); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(in, node); |
| ObjectInputStream result = entry.convertToType(ObjectInputStream.class, node, null); |
| assertNull(result); // TODO: is this the expected result? |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testInputStreamToSerializableSameType() throws Exception { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| try (ObjectOutputStream oos = new ObjectOutputStream(out)) { |
| oos.writeObject(Maps.newHashMap()); |
| } |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(new ByteArrayInputStream(out.toByteArray()), node); |
| // same type |
| Map<?,?> result = entry.convertToType(HashMap.class, node, null); |
| assertNotNull(result); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testInputStreamToSerializable() throws Exception { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| try (ObjectOutputStream oos = new ObjectOutputStream(out)) { |
| oos.writeObject(new LinkedHashMap<>()); |
| } |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(new ByteArrayInputStream(out.toByteArray()), node); |
| // different type that cannot be converted |
| Calendar result = entry.convertToType(Calendar.class, node, LinkedHashMap.class.getClassLoader()); |
| assertNull(result); |
| |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testBinaryPropertyToObjectInputStream() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.BINARY); |
| when(prop.getStream()).thenReturn(new ByteArrayInputStream("value".getBytes())); |
| when(prop.getValue()).thenReturn(vf.createValue(new ByteArrayInputStream("value".getBytes()))); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| ObjectInputStream result = entry.convertToType(ObjectInputStream.class, node, null); |
| assertNull(result); // TODO: is this the expected result? |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValue(); |
| verify(prop).getType(); |
| verifyNoMoreInteractions(prop); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testMvPropertyToBoolean() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.STRING); |
| when(prop.isMultiple()).thenReturn(true); |
| when(prop.getValue()).thenThrow(new ValueFormatException("multi-valued")); |
| Value[] vs = new Value[] {vf.createValue("true"), vf.createValue("false")}; |
| when(prop.getValues()).thenReturn(vs); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| assertTrue(entry.isArray()); |
| |
| Boolean result = entry.convertToType(Boolean.class, node, null); |
| assertNotNull(result); |
| assertTrue(result); |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValues(); |
| verify(prop).getType(); |
| verifyNoMoreInteractions(prop); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testEmptyMvPropertyToString() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.STRING); |
| when(prop.isMultiple()).thenReturn(true); |
| when(prop.getValue()).thenThrow(new ValueFormatException("multi-valued")); |
| Value[] vs = new Value[0]; |
| when(prop.getValues()).thenReturn(vs); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| assertTrue(entry.isArray()); |
| |
| String result = entry.convertToType(String.class, node, null); |
| assertNull(result); |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValues(); |
| verify(prop).getType(); |
| verifyNoMoreInteractions(prop); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testConversionFails() throws RepositoryException { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.STRING); |
| when(prop.isMultiple()).thenReturn(false); |
| when(prop.getValue()).thenReturn(vf.createValue("string")); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| assertFalse(entry.isArray()); |
| |
| Short result = entry.convertToType(Short.class, node, null); |
| assertNull(result); |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValue(); |
| verify(prop).getType(); |
| verifyNoMoreInteractions(prop); |
| verifyZeroInteractions(node); |
| } |
| |
| @Test |
| public void testStringToValue() throws RepositoryException { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.STRING); |
| when(prop.isMultiple()).thenReturn(false); |
| when(prop.getValue()).thenReturn(vf.createValue("string")); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| assertFalse(entry.isArray()); |
| |
| Value result = entry.convertToType(Value.class, node, null); |
| assertNotNull(result); |
| assertEquals(PropertyType.STRING, result.getType()); |
| assertEquals("string", result.getString()); |
| |
| verify(prop, times(2)).isMultiple(); |
| verify(prop).getValue(); |
| verify(prop).getType(); |
| verify(node).getSession(); |
| verifyNoMoreInteractions(prop, node); |
| } |
| |
| @Test |
| public void testConvertToSameType() throws Exception { |
| Calendar cal = Calendar.getInstance(); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(cal, node); |
| Calendar result = entry.convertToType(Calendar.class, node, null); |
| |
| assertSame(cal, result); |
| verify(node).getSession(); |
| verifyNoMoreInteractions(node); |
| } |
| |
| @Test |
| public void testStringToProperty() throws Exception { |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry("value", node); |
| Property result = entry.convertToType(Property.class, node, null); |
| assertNull(result); // TODO is this expected? |
| |
| verify(node).getSession(); |
| verify(session).getValueFactory(); |
| verifyNoMoreInteractions(node, session); |
| } |
| |
| @Test |
| public void testPropertyToProperty() throws Exception { |
| Property prop = mock(Property.class); |
| when(prop.getType()).thenReturn(PropertyType.BOOLEAN); |
| when(prop.getValue()).thenReturn(BooleanValue.valueOf("true")); |
| |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop); |
| Property result = entry.convertToType(Property.class, node, null); |
| assertSame(prop, result); |
| |
| verifyZeroInteractions(node); |
| verify(prop).getType(); |
| verify(prop).getValue(); |
| verify(prop, times(2)).isMultiple(); |
| verifyNoMoreInteractions(prop); |
| } |
| |
| @Test |
| public void testCreateFromSerializable() throws Exception { |
| Object value = new HashMap<>(); |
| JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(value, node); |
| Object propValue = entry.getPropertyValue(); |
| assertTrue(propValue instanceof HashMap); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testCreateFromUnstorableValue() throws Exception { |
| Object value = new TestClass(); |
| new JcrPropertyMapCacheEntry(value, node); |
| } |
| |
| private static final class TestClass {} |
| } |