Java tutorial
/*************************************************************** * This file is part of the [fleXive](R) framework. * * Copyright (c) 1999-2014 * UCS - unique computing solutions gmbh (http://www.ucs.at) * All rights reserved * * The [fleXive](R) project is free software; you can redistribute * it and/or modify it under the terms of the GNU Lesser General Public * License version 2.1 or higher as published by the Free Software Foundation. * * The GNU Lesser General Public License can be found at * http://www.gnu.org/licenses/lgpl.html. * A copy is found in the textfile LGPL.txt and important notices to the * license from the author are found in LICENSE.txt distributed with * these libraries. * * This library 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. * * For further information about UCS - unique computing solutions gmbh, * please see the company website: http://www.ucs.at * * For further information about [fleXive](R), please see the * project website: http://www.flexive.org * * * This copyright notice MUST APPEAR in all copies of the file! ***************************************************************/ package com.flexive.tests.embedded.persistence; import com.flexive.shared.CacheAdmin; import com.flexive.shared.EJBLookup; import com.flexive.shared.FxLanguage; import com.flexive.shared.content.FxContent; import com.flexive.shared.content.FxPK; import com.flexive.shared.exceptions.FxApplicationException; import com.flexive.shared.exceptions.FxLogoutFailedException; import com.flexive.shared.interfaces.AssignmentEngine; import com.flexive.shared.interfaces.ContentEngine; import com.flexive.shared.interfaces.TypeEngine; import com.flexive.shared.security.ACL; import com.flexive.shared.security.ACLCategory; import com.flexive.shared.structure.*; import com.flexive.shared.value.*; import com.flexive.tests.embedded.FxTestUtils; import com.flexive.tests.embedded.TestUsers; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.*; import static com.flexive.tests.embedded.FxTestUtils.login; import static com.flexive.tests.embedded.FxTestUtils.logout; /** * Tests for FxValues (single/multi language, store/load) * * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at) */ @Test(groups = { "ejb", "valuetest" }) public class ValueTest { private static final Log LOG = LogFactory.getLog(ValueTest.class); private ContentEngine co; private TypeEngine type; private AssignmentEngine ass; private final static String TYPE_NAME = "TESTVALUES_" + RandomStringUtils.random(16, true, true); private ACL aclStructure, aclWorkflow, aclContent; private long typeId; private FxType REF_TYPE1, REF_TYPE2; private FxPK RPK1, RPK2; /** * setup... * * @throws Exception on errors */ @BeforeClass public void beforeClass() throws Exception { co = EJBLookup.getContentEngine(); type = EJBLookup.getTypeEngine(); ass = EJBLookup.getAssignmentEngine(); login(TestUsers.SUPERVISOR); //create the base type ACL[] tmp = FxTestUtils.createACLs(new String[] { "STRUCTURE_" + RandomStringUtils.random(16, true, true), "WORKFLOW_" + RandomStringUtils.random(16, true, true), "CONTENT_" + RandomStringUtils.random(16, true, true) }, new ACLCategory[] { ACLCategory.STRUCTURE, ACLCategory.WORKFLOW, ACLCategory.INSTANCE }, TestUsers.getTestMandator()); aclStructure = tmp[0]; aclWorkflow = tmp[1]; aclContent = tmp[2]; typeId = type.save(FxTypeEdit.createNew(TYPE_NAME, new FxString("Test data"), aclStructure, null)); //create referenced types long rt1 = type.save( FxTypeEdit.createNew("Referenced Test Type 1", new FxString("Test data"), aclStructure, null)); REF_TYPE1 = CacheAdmin.getEnvironment().getType(rt1); long rt2 = type.save( FxTypeEdit.createNew("Referenced Test Type 2", new FxString("Test data"), aclStructure, null)); REF_TYPE2 = CacheAdmin.getEnvironment().getType(rt2); //create single test entries for both referenced types FxContent co1 = co.initialize(REF_TYPE1.getId()); RPK1 = new FxPK(co.save(co1).getId(), 1); //fix to set it to max version instead of specific FxContent co2 = co.initialize(REF_TYPE2.getId()); RPK2 = new FxPK(co.save(co2).getId(), 1); //fix to set it to max version instead of specific } private void createProperty(FxDataType dataType) throws FxApplicationException { FxPropertyEdit prop = FxPropertyEdit .createNew("VTS" + dataType.name(), new FxString("UnitTest for " + dataType.name()), new FxString("hint..."), FxMultiplicity.of(1, 1), aclStructure, dataType) .setMultiLang(false).setOverrideMultiLang(true); switch (dataType) { case Reference: prop.setReferencedType(REF_TYPE1); break; default: //nothing } long propId = ass.createProperty(typeId, prop, "/"); FxPropertyAssignment paSingle = (FxPropertyAssignment) CacheAdmin.getEnvironment().getAssignment(propId); FxPropertyAssignmentEdit pe = FxPropertyAssignmentEdit .createNew(paSingle, paSingle.getAssignedType(), "VTM" + dataType.name(), "/").setMultiLang(true); ass.save(pe, false); } private void removeProperty(FxDataType dataType) throws FxApplicationException { long assId = CacheAdmin.getEnvironment() .getAssignment(TYPE_NAME.toUpperCase() + "/VTS" + dataType.name().toUpperCase()).getId(); ass.removeAssignment(assId, true, true); } @AfterClass(dependsOnMethods = { "tearDownStructures" }) public void afterClass() throws FxLogoutFailedException, FxApplicationException { logout(); } @AfterClass public void tearDownStructures() throws Exception { long typeId = CacheAdmin.getEnvironment().getType(TYPE_NAME).getId(); co.removeForType(typeId); type.remove(typeId); co.remove(RPK1); co.remove(RPK2); type.remove(REF_TYPE1.getId()); type.remove(REF_TYPE2.getId()); FxTestUtils.removeACL(aclStructure, aclWorkflow, aclContent); } class TestData<T extends FxValue> { FxDataType dataType; T _single; T _multi; Object en_value; Object de_value; @SuppressWarnings({ "unchecked" }) public TestData(FxDataType dataType, T _single, T _multi) { Assert.assertTrue(!_single.isMultiLanguage(), "1st value argument has to be single language!"); Assert.assertTrue(_multi.isMultiLanguage(), "2nd value argument has to be multi language!"); this.dataType = dataType; this._single = _single; this._multi = _multi; en_value = _single.getBestTranslation(); de_value = _multi.getBestTranslation(); this._single.setTranslation(FxLanguage.ENGLISH, en_value); this._multi.setTranslation(FxLanguage.ENGLISH, en_value); this._multi.setTranslation(FxLanguage.GERMAN, de_value); this._multi.setDefaultLanguage(FxLanguage.ENGLISH); this._single.setValueData(42); this._multi.setValueData(43); } @SuppressWarnings({ "unchecked" }) public void testConsistency() throws Exception { Assert.assertTrue(!_single.equals(_multi)); Assert.assertTrue(_single.getDefaultTranslation().equals(_multi.getDefaultTranslation())); Assert.assertTrue(_multi.getTranslation(FxLanguage.ENGLISH).equals(en_value)); Assert.assertTrue(_multi.getTranslation(FxLanguage.GERMAN).equals(de_value)); Assert.assertTrue(_multi.getTranslatedLanguages().length == 2); Assert.assertTrue(_single.getTranslatedLanguages().length == 1); Assert.assertTrue(_single.getTranslation(FxLanguage.GERMAN).equals(en_value)); _single.setTranslation(FxLanguage.ENGLISH, de_value); Assert.assertTrue(_single.getTranslation(FxLanguage.GERMAN).equals(de_value)); _single.setDefaultLanguage(FxLanguage.ITALIAN); Assert.assertTrue(!_single.hasDefaultLanguage()); Assert.assertTrue(_single.getTranslation(FxLanguage.ENGLISH).equals(de_value)); Assert.assertTrue(_multi.hasDefaultLanguage()); checkValueDataClearing(_single, 42); checkValueDataClearing(_multi, 43); } private void checkValueDataClearing(T value, int data) { Assert.assertEquals((int) value.getValueData(), data); value.setValueData(data + 13); Assert.assertEquals((int) value.getValueData(), data + 13); Assert.assertTrue(value.hasValueData()); value.clearValueData(); Assert.assertFalse(value.hasValueData()); value.setValueData(data); Assert.assertTrue(value.hasValueData()); } public void testSingleValue(FxValue compare) throws Exception { if (compare instanceof FxBinary) { BinaryDescriptor desc = ((FxBinary) compare).getBestTranslation(); Assert.assertTrue(desc.isImage(), "Expected an image!"); Assert.assertTrue(desc.getWidth() == 2048, "Wrong image width!"); Assert.assertTrue(desc.getHeight() == 1536, "Wrong image height!"); Assert.assertTrue(desc.getResolution() == 72.0 || desc.getResolution() == 180.0, "Wrong image resolution! Expected [72.0] or [180.0] depending on ImageMagick version but got [" + desc.getResolution() + "]"); //download File f = File.createTempFile("FxBinary", ".bin"); FileOutputStream fout = new FileOutputStream(f); System.out.println("b4 download of " + f.getAbsolutePath() + " ..."); long time = System.currentTimeMillis(); ((FxBinary) compare).getBestTranslation().download(fout); System.out.println("download of " + f.getAbsolutePath() + " took " + (System.currentTimeMillis() - time) + "[ms]!"); fout.close(); f.deleteOnExit(); return; } else if (compare instanceof FxHTML) { Assert.assertTrue( ((String) compare.getBestTranslation()).indexOf((String) _single.getBestTranslation()) >= 0, "Original single value was not found in tidied value!"); return; } //cant use regular compare since even single language values will be loaded as multi language if the assignment is multilinugual! Assert.assertTrue(_single.getBestTranslation().equals(compare.getBestTranslation()), _single.getClass().getCanonicalName() + " mismatch for single language value (DataType " + dataType.name() + "): " + _single.toString() + "!=" + compare.toString()); } public void testMultiValue(FxValue compare) throws Exception { if (compare instanceof FxBinary) return; //cant test this yet // else if( compare instanceof FxHTML ) { // return; // } Assert.assertTrue(_multi.equals(compare), _multi.getClass().getCanonicalName() + " mismatch for multi language value (DataType " + dataType.name() + "): " + _multi.toString() + "!=" + compare.toString()); } } @Test public void valueTest() throws Exception { GregorianCalendar gc_multi_date = new GregorianCalendar(1940, 11, 22); GregorianCalendar gc_multi_date2 = new GregorianCalendar(1997, 9, 21); GregorianCalendar gc_single_date = new GregorianCalendar(1974, 0, 12); GregorianCalendar gc_single_date2 = new GregorianCalendar(1974, 3, 17); GregorianCalendar gc_multi_datetime = new GregorianCalendar(1940, 11, 22, 3, 30, 20); GregorianCalendar gc_multi_datetime2 = new GregorianCalendar(1997, 9, 21, 7, 40, 30); GregorianCalendar gc_single_datetime = new GregorianCalendar(1974, 0, 12, 4, 35, 45); GregorianCalendar gc_single_datetime2 = new GregorianCalendar(1974, 3, 17, 14, 30, 15); String s_single = "ABC"; String s_multi = "DEF"; String s_single_big = RandomStringUtils.randomAlphanumeric(50000); String s_multi_big = RandomStringUtils.randomAlphanumeric(50000); File testFile = new File("test.file"); if (!testFile.exists()) testFile = new File("src/framework/testresources/image/Exif.JPG"); if (!testFile.exists()) return; FileInputStream fis = new FileInputStream(testFile); long time = System.currentTimeMillis(); BinaryDescriptor binary = new BinaryDescriptor(testFile.getName(), testFile.length(), fis); System.out.println("size: " + binary.getSize() + " time: " + (System.currentTimeMillis() - time)); System.out.println("==valueTest== Handle received for " + binary.getName() + ": " + binary.getHandle()); fis.close(); TestData[] data = { new TestData<FxHTML>(FxDataType.HTML, new FxHTML(false, s_single).setTidyHTML(true), new FxHTML(true, s_multi)), new TestData<FxString>(FxDataType.String1024, new FxString(false, s_single), new FxString(true, s_multi)), new TestData<FxString>(FxDataType.Text, new FxString(false, s_single_big), new FxString(true, s_multi_big)), new TestData<FxNumber>(FxDataType.Number, new FxNumber(false, Integer.MAX_VALUE), new FxNumber(true, Integer.MIN_VALUE)), new TestData<FxLargeNumber>(FxDataType.LargeNumber, new FxLargeNumber(false, Long.MAX_VALUE), new FxLargeNumber(true, Long.MIN_VALUE)), new TestData<FxFloat>(FxDataType.Float, new FxFloat(false, 123213213213.2222221f), new FxFloat(true, 1f)), new TestData<FxDouble>(FxDataType.Double, new FxDouble(false, 0.000000000000001d), new FxDouble(true, 1d)), new TestData<FxBoolean>(FxDataType.Boolean, new FxBoolean(false, true), new FxBoolean(true, false)), new TestData<FxDate>(FxDataType.Date, new FxDate(false, gc_single_date.getTime()), new FxDate(true, gc_multi_date.getTime())), new TestData<FxDateTime>(FxDataType.DateTime, new FxDateTime(false, gc_single_datetime.getTime()), new FxDateTime(true, gc_multi_datetime.getTime())), new TestData<FxDateRange>(FxDataType.DateRange, new FxDateRange(false, new DateRange(gc_single_date.getTime(), gc_single_date2.getTime())), new FxDateRange(true, new DateRange(gc_multi_date.getTime(), gc_multi_date2.getTime()))), new TestData<FxDateTimeRange>(FxDataType.DateTimeRange, new FxDateTimeRange(false, new DateRange(gc_single_datetime.getTime(), gc_single_datetime2.getTime())), new FxDateTimeRange(true, new DateRange(gc_multi_datetime.getTime(), gc_multi_datetime2.getTime()))), new TestData<FxBinary>(FxDataType.Binary, new FxBinary(false, binary), new FxBinary(true, binary)), new TestData<FxReference>(FxDataType.Reference, new FxReference(false, new ReferencedContent(RPK1)), new FxReference(true, new ReferencedContent(RPK1))) }; FxType testType; StringBuilder sbErr = new StringBuilder(100); for (TestData test : data) { try { System.out.println("Testing " + test.dataType.name() + " ..."); test.testConsistency(); createProperty(test.dataType); testType = CacheAdmin.getEnvironment().getType(TYPE_NAME); FxContent content = co.initialize(testType.getId()); content.setValue("/VTS" + test.dataType.name() + "[1]", test._single.copy()); // content.getPropertyData("/VT" + test.dataType.name() + "[1]").createNew(FxPropertyData.POSITION_BOTTOM); content.setValue("/VTM" + test.dataType.name() + "[1]", test._multi.copy().setValueData(43)); FxPK pk = co.save(content); FxContent loaded = co.load(pk); FxValue loadedSingle = loaded.getPropertyData("/VTS" + test.dataType.name() + "[1]").getValue(); FxValue loadedMulti = loaded.getPropertyData("/VTM" + test.dataType.name() + "[1]").getValue(); test.testSingleValue(loadedSingle); test.testMultiValue(loadedMulti); Assert.assertEquals((int) loadedSingle.getValueData(), 42); Assert.assertEquals((int) loadedMulti.getValueData(), 43); pk = co.save(loaded); loaded = co.load(pk); loadedSingle = loaded.getPropertyData("/VTS" + test.dataType.name() + "[1]").getValue(); loadedMulti = loaded.getPropertyData("/VTM" + test.dataType.name() + "[1]").getValue(); test.testSingleValue(loadedSingle); test.testMultiValue(loadedMulti); Assert.assertEquals((int) loadedSingle.getValueData(), 42); Assert.assertEquals((int) loadedMulti.getValueData(), 43); co.remove(pk); if (test.dataType == FxDataType.Reference) { //additional tests content = co.initialize(testType.getId()); content.setValue("/VTM" + test.dataType.name() + "[1]", new FxReference(true, new ReferencedContent(RPK1))); try { //set to a new pk content.setValue("/VTS" + test.dataType.name() + "[1]", new FxReference(false, new ReferencedContent(new FxPK()))); co.save(content); //expected to fail Assert.fail("Invalid PK (new) for a reference should fail!"); } catch (Exception e) { //expected } try { //set to a non existing pk content.setValue("/VTS" + test.dataType.name() + "[1]", new FxReference(false, new ReferencedContent(new FxPK(123456)))); co.save(content); //expected to fail Assert.fail("Invalid PK (non existant) for a reference should fail!"); } catch (Exception e) { //expected } try { //set to an existing pk, but wrong type content.setValue("/VTS" + test.dataType.name() + "[1]", new FxReference(false, new ReferencedContent(RPK2))); co.save(content); //expected to fail Assert.fail("Invalid PK (wrong type) for a reference should fail!"); } catch (Exception e) { //expected } try { //set to an existing pk, but wrong type content.setValue("/VTS" + test.dataType.name() + "[1]", RPK1); co.save(content); //expected to work } catch (Exception e) { e.printStackTrace(); Assert.fail("Correct PK for a reference should not fail!"); //expected } } } catch (Throwable e) { sbErr.append("Failed DataType: [").append(test.dataType.name()).append("] with: ") .append(e.getMessage()).append("\n"); e.printStackTrace(); } finally { try { removeProperty(test.dataType); } catch (Exception e) { LOG.warn("Failed to remove property", e); } } } if (sbErr.length() > 0) Assert.fail(sbErr.toString()); } /** * Basic tests of FxValue's {@link Comparable} implementation */ @Test public void compareToTest() { final List<FxString> strings = new ArrayList<FxString>( Arrays.asList(new FxString("b"), new FxString("a"), new FxString("c"), new FxString("a0"))); Collections.sort(strings); final String sortedStrings = StringUtils.join(strings.iterator(), ','); Assert.assertTrue(sortedStrings.equals("a,a0,b,c"), "Expected lexical order 'a,a0,b,c', got: " + sortedStrings); } }