/* * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.repo.domain.propval; import java.io.Serializable; import java.util.Date; import java.util.Random; import junit.framework.TestCase; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ISO8601DateFormat; import org.alfresco.util.Pair; import org.springframework.context.ApplicationContext; /** * @see PropertyValueDAO * * @author Derek Hulley * @since 3.3 */ public class PropertyValueDAOTest extends TestCase { private ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); private TransactionService transactionService; private RetryingTransactionHelper txnHelper; private PropertyValueDAO propertyValueDAO; @Override public void setUp() throws Exception { ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); transactionService = serviceRegistry.getTransactionService(); txnHelper = transactionService.getRetryingTransactionHelper(); propertyValueDAO = (PropertyValueDAO) ctx.getBean("propertyValueDAO"); } public void testPropertyClass() throws Exception { final Class clazz = this.getClass(); RetryingTransactionCallback>> createClassCallback = new RetryingTransactionCallback>>() { public Pair> execute() throws Throwable { // Get the classes return propertyValueDAO.getOrCreatePropertyClass(clazz); } }; final Pair> clazzEntityPair = txnHelper.doInTransaction(createClassCallback, false); assertNotNull(clazzEntityPair); assertNotNull(clazzEntityPair.getFirst()); assertEquals(clazz, clazzEntityPair.getSecond()); // Now retrieve it RetryingTransactionCallback getClassCallback = new RetryingTransactionCallback() { public Void execute() throws Throwable { Pair> checkPair1 = propertyValueDAO.getPropertyClassById(clazzEntityPair.getFirst()); assertEquals(clazzEntityPair, checkPair1); Pair> checkPair2 = propertyValueDAO.getPropertyClass(clazzEntityPair.getSecond()); assertEquals(clazzEntityPair, checkPair2); return null; } }; txnHelper.doInTransaction(getClassCallback, true); // Test failure when requesting invalid ID RetryingTransactionCallback badGetCallback = new RetryingTransactionCallback() { public Void execute() throws Throwable { propertyValueDAO.getPropertyClassById(Long.MIN_VALUE); return null; } }; try { txnHelper.doInTransaction(badGetCallback, false); fail("Expected exception when using invalid ID."); } catch (RuntimeException e) { // Expected } // Test null caching RetryingTransactionCallback noHitCallback = new RetryingTransactionCallback() { public Void execute() throws Throwable { propertyValueDAO.getPropertyClass(this.getClass()); propertyValueDAO.getPropertyClass(this.getClass()); return null; } }; txnHelper.doInTransaction(noHitCallback, false); } public void testPropertyDateValue() throws Exception { final Date dateValue = ISO8601DateFormat.parse("1936-08-04T23:37:25.793Z"); final Date dateValueBack = ISO8601DateFormat.parse("1936-08-04T00:00:00.000Z"); RetryingTransactionCallback> createValueCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getOrCreatePropertyDateValue(dateValue); } }; final Pair entityPair = txnHelper.doInTransaction(createValueCallback, false); assertNotNull(entityPair); assertEquals(dateValueBack, entityPair.getSecond()); RetryingTransactionCallback> getValueCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getPropertyDateValue(dateValue); } }; final Pair entityPairCheck = txnHelper.doInTransaction(getValueCallback, false); assertNotNull(entityPairCheck); assertEquals(entityPair, entityPairCheck); } public void testPropertyStringValue() throws Exception { final String stringValue = "One Two Three - " + System.currentTimeMillis(); final String stringValueUpper = stringValue.toUpperCase(); final String stringValueLower = stringValue.toLowerCase(); RetryingTransactionCallback> createStringCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getOrCreatePropertyStringValue(stringValue); } }; final Pair stringEntityPair = txnHelper.doInTransaction(createStringCallback, false); assertNotNull(stringEntityPair); assertNotNull(stringEntityPair.getFirst()); assertEquals(stringValue, stringEntityPair.getSecond()); // Check that the uppercase and lowercase strings don't have entries RetryingTransactionCallback getClassCallback = new RetryingTransactionCallback() { public Void execute() throws Throwable { Pair checkPair1 = propertyValueDAO.getPropertyStringValue(stringValue); assertNotNull(checkPair1); assertEquals(stringValue, checkPair1.getSecond()); Pair checkPair2 = propertyValueDAO.getPropertyStringValue(stringValueUpper); assertNull(checkPair2); Pair checkPair3 = propertyValueDAO.getPropertyStringValue(stringValueLower); assertNull(checkPair3); return null; } }; txnHelper.doInTransaction(getClassCallback, true); RetryingTransactionCallback> createStringUpperCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getOrCreatePropertyStringValue(stringValueUpper); } }; final Pair stringUpperEntityPair = txnHelper.doInTransaction(createStringUpperCallback, false); assertNotNull(stringUpperEntityPair); assertNotNull(stringUpperEntityPair.getFirst()); assertEquals(stringValueUpper, stringUpperEntityPair.getSecond()); assertNotSame("String IDs were not different", stringEntityPair.getFirst(), stringUpperEntityPair.getFirst()); } public void testPropertyDoubleValue() throws Exception { final Double doubleValue = Double.valueOf(1.7976931348623E+308); RetryingTransactionCallback> createValueCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getOrCreatePropertyDoubleValue(doubleValue); } }; final Pair entityPair = txnHelper.doInTransaction(createValueCallback, false); assertNotNull(entityPair); assertEquals(doubleValue, entityPair.getSecond()); RetryingTransactionCallback> getValueCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getPropertyDoubleValue(doubleValue); } }; final Pair entityPairCheck = txnHelper.doInTransaction(getValueCallback, false); assertNotNull(entityPairCheck); assertEquals(entityPair, entityPairCheck); } /** * Tests that the given value can be persisted and retrieved with the same resulting ID */ private void runPropertyValueTest(final Serializable value) throws Exception { // Create it (if it doesn't exist) RetryingTransactionCallback> createValueCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getOrCreatePropertyValue(value); } }; final Pair entityPair = txnHelper.doInTransaction(createValueCallback, false); assertNotNull(entityPair); assertEquals(value, entityPair.getSecond()); // Retrieve it by value RetryingTransactionCallback> getValueCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getPropertyValue(value); } }; final Pair entityPairCheck = txnHelper.doInTransaction(getValueCallback, false); assertNotNull(entityPairCheck); assertEquals(entityPair, entityPairCheck); // Retrieve it by ID RetryingTransactionCallback> getByIdCallback = new RetryingTransactionCallback>() { public Pair execute() throws Throwable { // Get the classes return propertyValueDAO.getPropertyValueById(entityPair.getFirst()); } }; final Pair entityPairCheck2 = txnHelper.doInTransaction(getByIdCallback, false); assertNotNull(entityPairCheck2); assertEquals(entityPair, entityPairCheck2); } public void testPropertyValue_Null() throws Exception { runPropertyValueTest(null); } public void testPropertyValue_Boolean() throws Exception { runPropertyValueTest(Boolean.TRUE); runPropertyValueTest(Boolean.FALSE); } public void testPropertyValue_Short() throws Exception { for (short i = 0; i < 100; i++) { runPropertyValueTest(new Short(i)); } } public void testPropertyValue_Integer() throws Exception { for (int i = 0; i < 100; i++) { runPropertyValueTest(new Integer(i)); } } public void testPropertyValue_Long() throws Exception { for (long i = 0; i < 100; i++) { runPropertyValueTest(new Long(i)); } } public void testPropertyValue_Float() throws Exception { for (long i = 0; i < 100; i++) { runPropertyValueTest(new Float((float)i + 0.01F)); } } public void testPropertyValue_Double() throws Exception { for (long i = 0; i < 100; i++) { runPropertyValueTest(new Double((double)i + 0.01D)); } } public void testPropertyValue_Date() throws Exception { Random rand = new Random(); for (long i = 0; i < 1000; i++) { runPropertyValueTest(new Date(rand.nextLong())); } } public void testPropertyValue_String() throws Exception { for (long i = 0; i < 100; i++) { runPropertyValueTest(new String("Value-" + i + ".xyz")); } } private void removeCaches() { ((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyClassCache(null); ((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyDateValueCache(null); ((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyDoubleValueCache(null); ((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyStringValueCache(null); ((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyValueCache(null); } public void testPropertyClass_NoCache() throws Exception { removeCaches(); testPropertyClass(); } public void testPropertyDateValue_NoCache() throws Exception { removeCaches(); testPropertyDateValue(); } public void testPropertyStringValue_NoCache() throws Exception { removeCaches(); testPropertyStringValue(); } public void testPropertyDoubleValue_NoCache() throws Exception { removeCaches(); testPropertyDoubleValue(); } }