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.XPathElement; import com.flexive.shared.content.FxContent; import com.flexive.shared.content.FxPK; import com.flexive.shared.exceptions.*; import com.flexive.shared.interfaces.*; import com.flexive.shared.media.FxMimeTypeWrapper; import com.flexive.shared.security.ACL; import com.flexive.shared.security.ACLCategory; import com.flexive.shared.security.Mandator; import com.flexive.shared.structure.*; import com.flexive.shared.value.FxSelectOne; import com.flexive.shared.value.FxString; import com.flexive.shared.value.FxValue; import com.flexive.tests.embedded.TestUsers; import com.google.common.collect.Lists; import org.apache.commons.lang.RandomStringUtils; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import javax.naming.Context; import javax.transaction.UserTransaction; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static com.flexive.shared.CacheAdmin.getEnvironment; import static com.flexive.shared.EJBLookup.getTypeEngine; import static com.flexive.tests.embedded.FxTestUtils.login; import static com.flexive.tests.embedded.FxTestUtils.logout; import static org.testng.Assert.*; /** * Structure tests * * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at) */ @Test public class StructureTest { private TypeEngine te; private AssignmentEngine ae; private ACLEngine acl; private ContentEngine ce; @BeforeClass(groups = { "ejb", "structure" }) public void beforeClass() throws FxLookupException, FxLoginFailedException, FxAccountInUseException { te = getTypeEngine(); ae = EJBLookup.getAssignmentEngine(); acl = EJBLookup.getAclEngine(); ce = EJBLookup.getContentEngine(); login(TestUsers.SUPERVISOR); } @AfterClass(groups = { "ejb", "structure" }) public void afterClass() throws Exception { try { te.remove(env().getType("ContactsTest").getId()); } catch (FxRuntimeException e) { // ignore } try { ae.removeAssignment(env().getAssignment("ROOT/CONTACT_DATA").getId(), true, false); } catch (FxRuntimeException e) { // ignore } try { acl.remove(env().getACL("ContactsTest").getId()); } catch (FxRuntimeException e) { // ignore } logout(); } @Test(groups = { "ejb", "structure" }, invocationCount = 2) public void typeCreateDeleteUpdate() throws Exception { long testId = -1; try { testId = te.save(FxTypeEdit.createNew("TestCD", new FxString("description..."), env().getACL(ACLCategory.STRUCTURE.getDefaultId()), null)); FxString desc = new FxString("Test data structure"); desc.setTranslation(FxLanguage.GERMAN, "Testdaten Strukturen"); FxString hint = new FxString("Hint text ..."); FxGroupEdit ge = FxGroupEdit.createNew("TEST_DIRECT_DATA", desc, hint, true, FxMultiplicity.of(0, 1)); ae.createGroup(testId, ge, "/"); ACL structACL = null; for (ACL a : env().getACLs()) if (a.getCategory() == ACLCategory.STRUCTURE) { structACL = a; break; } assertTrue(structACL != null, "No available ACL for structure found!"); FxPropertyEdit pe = FxPropertyEdit.createNew("TestDirectProperty1", desc, hint, true, FxMultiplicity.of(0, 1), true, structACL, FxDataType.String1024, new FxString(FxString.EMPTY), true, null, null, null); ae.createProperty(testId, pe, "/"); pe.setName("TestDirectProperty2"); pe.setDataType(FxDataType.String1024); pe.setMultiplicity(FxMultiplicity.of(1, 1)); ae.createProperty(testId, pe, "/"); pe.setName("TestDirectProperty3"); pe.setDataType(FxDataType.String1024); pe.setMultiplicity(FxMultiplicity.of(0, 5)); ae.createProperty(testId, pe, "/"); } catch (FxApplicationException e) { Assert.fail(e.getMessage()); } FxTypeEdit testEdit = new FxTypeEdit(env().getType("TestCD")); long propCount = testEdit.getAssignedProperties().size(); testEdit.setName("TestCDNewName"); testEdit.setPermissions((byte) 0); //clear permissions testEdit.setUseInstancePermissions(true); testEdit.setLabel(new FxString("Changed label")); testEdit.setState(TypeState.Unavailable); te.save(testEdit); FxType testType = env().getType("TestCDNewName"); assertTrue(testType.getAssignedProperties().size() == propCount, "Property count mismatch"); assertEquals(testType.getAssignment("/TestDirectProperty2").getXPath(), "TESTCDNEWNAME/TESTDIRECTPROPERTY2", "Expected [TESTCDNEWNAME/TESTDIRECTPROPERTY2] but got: [" + testType.getAssignment("/TestDirectProperty2").getXPath() + "]"); assertTrue(testType.isUsePermissions()); assertTrue(testType.isUseInstancePermissions()); assertTrue(!testType.isUsePropertyPermissions()); assertTrue(!testType.isUseStepPermissions()); assertTrue(!testType.isUseTypePermissions()); assertTrue(testType.getState() == TypeState.Unavailable); try { assertTrue(testId == testType.getId(), "Wrong id for type!"); te.remove(testType.getId()); try { env().getType("TestCD"); Assert.fail("TestCD could be loaded after remove!"); } catch (Exception e) { //ok } } catch (FxApplicationException e) { Assert.fail(e.getMessage()); } } /** * Test derived types * * @throws Exception on errors */ @Test(groups = { "ejb", "structure" }) public void derivedType() throws Exception { long testId = -1; try { testId = te.save(FxTypeEdit.createNew("TestCDP", new FxString("description..."), env().getACLs(ACLCategory.STRUCTURE).get(0), null)); // testId = te.create(1, 1, 1, new ArrayList<Mandator>(2), "TestCDP", // new FxString("description..."), null, false, // TypeStorageMode.Hierarchical, TypeCategory.User, TypeMode.Content, // true, LanguageMode.Multiple, TypeState.Available, (byte) 0, true, 0, 0, 0, 0); FxString desc = new FxString("Test data structure"); desc.setTranslation(FxLanguage.GERMAN, "Testdaten Strukturen"); FxString hint = new FxString("Hint text ..."); ACL structACL = null; for (ACL a : env().getACLs()) if (a.getCategory() == ACLCategory.STRUCTURE) { structACL = a; break; } assertTrue(structACL != null, "No available ACL for structure found!"); FxPropertyEdit pe = FxPropertyEdit.createNew("TestDirectProperty1", desc, hint, true, FxMultiplicity.of(0, 1), true, structACL, FxDataType.String1024, new FxString(FxString.EMPTY), true, null, null, null); ae.createProperty(testId, pe, "/"); FxGroupEdit ge = FxGroupEdit.createNew("TestGroup", desc, hint, true, FxMultiplicity.of(0, 1)); ae.createGroup(testId, ge, "/"); pe.setName("TestDirectProperty2"); pe.setMultiplicity(FxMultiplicity.of(0, 1)); ae.createProperty(testId, pe, "/TestGroup"); } catch (FxApplicationException e) { Assert.fail(e.getMessage()); } FxType testType = env().getType("TestCDP"); assertTrue(testId == testType.getId(), "Wrong id for type!"); long testDerivedId; testDerivedId = te .save(FxTypeEdit .createNew("TestCDDerived", new FxString("description..."), env().getACLs(ACLCategory.STRUCTURE).get(0), testType) .setEnableParentAssignments(false)); // testDerivedId = te.create(1, 1, 1, new ArrayList<Mandator>(2), "TestCDDerived", // new FxString("description..."), testType, false, // TypeStorageMode.Hierarchical, TypeCategory.User, TypeMode.Content, // true, LanguageMode.Multiple, TypeState.Available, (byte) 0, true, 0, 0, 0, 0); FxType testTypeDerived = env().getType("TestCDDerived"); assertTrue(testTypeDerived.getId() == testDerivedId, "Derived type id does not match!"); assertTrue(testTypeDerived.getParent().getId() == testType.getId(), "Derived types parent does not match!"); FxAssignment dp = null; try { dp = testTypeDerived.getAssignment("/TestDirectProperty1"); } catch (Exception e) { Assert.fail("Failed to retrieved derived property: " + e.getMessage()); } assertTrue(!dp.isEnabled(), "Property should be disabled!"); FxPropertyAssignmentEdit dpe = new FxPropertyAssignmentEdit((FxPropertyAssignment) dp); dpe.setEnabled(true); ae.save(dpe, false); testTypeDerived = env().getType("TestCDDerived"); dp = testTypeDerived.getAssignment("/TestDirectProperty1"); assertTrue(dp.isEnabled(), "Property should be enabled!"); try { dp = testTypeDerived.getAssignment("/TestGroup/TestDirectProperty2"); } catch (Exception e) { Assert.fail("Failed to retrieved derived property: " + e.getMessage()); } assertTrue(!dp.isEnabled(), "Property should be disabled!"); FxGroupAssignmentEdit gae = new FxGroupAssignmentEdit( (FxGroupAssignment) testTypeDerived.getAssignment("/TestGroup")); gae.setEnabled(true); ae.save(gae, false); testTypeDerived = env().getType("TestCDDerived"); dp = testTypeDerived.getAssignment("/TestGroup/TestDirectProperty2"); assertTrue(dp.isEnabled(), "Property should be enabled!"); try { te.remove(testTypeDerived.getId()); try { env().getType("TestCDDerived"); Assert.fail("TestCDDerived could be loaded after remove!"); } catch (Exception e) { //ok } te.remove(testType.getId()); try { env().getType("TestCDP"); Assert.fail("TestCD could be loaded after remove!"); } catch (Exception e) { //ok } } catch (FxApplicationException e) { Assert.fail(e.getMessage()); } } @Test(groups = { "ejb", "structure" }) public void contactData() throws Exception { try { if (env().getType("ContactsTest") != null) return; //ok, exists already } catch (Exception e) { //ok, create the type } long aid = acl.create("ContactsTest", new FxString("Contact ACL"), Mandator.MANDATOR_FLEXIVE, "#AA0000", "ACL for ContactsTest", ACLCategory.STRUCTURE); ACL contactACL = env().getACL(aid); FxString desc = new FxString("Template for contact data"); desc.setTranslation(FxLanguage.GERMAN, "Kontaktdaten Vorlage"); FxString hint = new FxString(""); FxGroupEdit ge = FxGroupEdit.createNew("CONTACT_DATA", desc, hint, true, FxMultiplicity.of(0, FxMultiplicity.N)); ae.createGroup(ge, "/"); ge.setName("ADDRESS"); desc.setTranslation(FxLanguage.ENGLISH, "Address"); desc.setTranslation(FxLanguage.GERMAN, "Adresse"); ge.setLabel(desc); ae.createGroup(ge, "/CONTACT_DATA"); desc.setTranslation(FxLanguage.ENGLISH, "Surname"); desc.setTranslation(FxLanguage.GERMAN, "Nachname"); hint.setTranslation(FxLanguage.ENGLISH, "Surname of the person"); hint.setTranslation(FxLanguage.GERMAN, "Nachname der Person"); FxPropertyEdit pe = FxPropertyEdit .createNew("SURNAME", desc, hint, FxMultiplicity.of(1, 1), contactACL, FxDataType.String1024) .setAutoUniquePropertyName(true); ae.createProperty(pe, "/CONTACT_DATA"); desc.setTranslation(FxLanguage.ENGLISH, "Name"); desc.setTranslation(FxLanguage.GERMAN, "Vorname"); hint.setTranslation(FxLanguage.ENGLISH, "Name of the person"); hint.setTranslation(FxLanguage.GERMAN, "Vorname der Person"); pe.setLabel(desc); pe.setHint(hint); pe.setName("NAME"); ae.createProperty(pe, "/CONTACT_DATA"); desc.setTranslation(FxLanguage.ENGLISH, "Street"); desc.setTranslation(FxLanguage.GERMAN, "Strasse"); pe.setLabel(desc); pe.setHint(desc); pe.setDataType(FxDataType.String1024); pe.setName("STREET"); ae.createProperty(pe, "/CONTACT_DATA/ADDRESS"); desc.setTranslation(FxLanguage.ENGLISH, "ZIP code"); desc.setTranslation(FxLanguage.GERMAN, "Postleitzahl"); pe.setDataType(FxDataType.String1024); pe.setLabel(desc); pe.setHint(desc); pe.setName("ZIP"); ae.createProperty(pe, "/CONTACT_DATA/ADDRESS"); desc.setTranslation(FxLanguage.ENGLISH, "City"); desc.setTranslation(FxLanguage.GERMAN, "Stadt"); pe.setLabel(desc); pe.setHint(desc); pe.setName("CITY"); ae.createProperty(pe, "/CONTACT_DATA/ADDRESS"); desc.setTranslation(FxLanguage.ENGLISH, "Country"); desc.setTranslation(FxLanguage.GERMAN, "Land"); pe.setLabel(desc); pe.setHint(desc); pe.setName("COUNTRY"); ae.createProperty(pe, "/CONTACT_DATA/ADDRESS"); te.save(FxTypeEdit.createNew("ContactsTest", new FxString("Contact data"), contactACL, null)); FxGroupAssignment ga = (FxGroupAssignment) env().getAssignment("ROOT/CONTACT_DATA"); FxGroupAssignmentEdit gae = FxGroupAssignmentEdit.createNew(ga, env().getType("ContactsTest"), null, "/"); ae.save(gae, true); } @Test(groups = { "ejb", "structure" }) public void assignmentGroupProperty() throws Exception { Context c = EJBLookup.getInitialContext(); UserTransaction ut = (UserTransaction) c.lookup("java:comp/UserTransaction"); ut.begin(); FxString desc = new FxString("group description..."); desc.setTranslation(2, "gruppen beschreibung"); final String GROUPNAME = "GROUPTEST" + RandomStringUtils.randomNumeric(5); FxGroupEdit ge = FxGroupEdit.createNew(GROUPNAME, desc, new FxString("hint..."), true, FxMultiplicity.of(0, FxMultiplicity.N)); ae.createGroup(ge, "/"); ge.setName("subgroup"); ae.createGroup(ge, "/" + GROUPNAME); ge.setName("subgroup2"); ae.createGroup(ge, "/" + GROUPNAME + "/SUBGROUP"); desc.setTranslation(1, "property description..."); desc.setTranslation(2, "attribut beschreibung..."); FxPropertyEdit pe = FxPropertyEdit.createNew("testproperty", desc, new FxString("property hint"), true, FxMultiplicity.of(1, 1), true, env().getACL(1), FxDataType.Number, new FxString("123"), true, null, null, null); ae.createProperty(pe, "/" + GROUPNAME + "/SUBGROUP"); FxGroupAssignment ga = (FxGroupAssignment) env().getAssignment("ROOT/" + GROUPNAME); FxGroupAssignmentEdit gae = FxGroupAssignmentEdit.createNew(ga, env().getType("ROOT"), "GTEST", "/"); ae.save(gae, true); ut.rollback(); } @Test(groups = { "ejb", "structure" }) public void assignmentRemove() throws Exception { long testId = -1; ACL structACL = null; FxString hint = new FxString("Hint text ..."); FxString desc = new FxString("Test data structure"); try { testId = te.save(FxTypeEdit.createNew("TestAssignmentRemove", new FxString("description..."), env().getACLs(ACLCategory.STRUCTURE).get(0), null)); desc.setTranslation(FxLanguage.GERMAN, "Testdaten Strukturen"); structACL = null; for (ACL a : env().getACLs()) if (a.getCategory() == ACLCategory.STRUCTURE) { structACL = a; break; } assertTrue(structACL != null, "No available ACL for structure found!"); FxPropertyEdit pe = FxPropertyEdit.createNew("TestAssignmentRemoveProperty1", desc, hint, true, FxMultiplicity.of(0, 1), true, structACL, FxDataType.String1024, new FxString(FxString.EMPTY), true, null, null, null); ae.createProperty(testId, pe, "/"); } catch (FxApplicationException e) { Assert.fail(e.getMessage()); } FxType testType = env().getType("TestAssignmentRemove"); assertTrue(testId == testType.getId(), "Wrong id for type!"); FxPropertyAssignment pa = null; long rmId = -1; try { pa = (FxPropertyAssignment) testType.getAssignment("/TestAssignmentRemoveProperty1"); assertTrue(pa != null, "Created Property Assignment is null!"); rmId = pa.getId(); } catch (Exception e) { Assert.fail("Created Property Assignment does not exist!"); } FxPropertyAssignmentEdit pae = FxPropertyAssignmentEdit.createNew(pa, testType, "TestAssignmentRemoveProperty2", "/"); try { long paId = ae.save(pae, true); pa = (FxPropertyAssignment) env().getAssignment(paId); } catch (Exception e) { Assert.fail("Failed to retrieve derived assignment(2): " + e.getMessage()); } //create derived assignment over 3 hops ae.save(FxPropertyAssignmentEdit.createNew(pa, testType, "TestAssignmentRemoveProperty3", "/"), true); //check base's testType = env().getType(testId); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty1") .getBaseAssignmentId() == FxAssignment.NO_PARENT); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty2").getBaseAssignmentId() == testType .getAssignment("/TestAssignmentRemoveProperty1").getId()); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty3").getBaseAssignmentId() == testType .getAssignment("/TestAssignmentRemoveProperty2").getId()); ae.removeAssignment(rmId, true, true); assertTrue( env().getSystemInternalRootPropertyAssignments().size() == env().getType(testId) .getAssignedProperties().size(), "Expected to have " + env().getSystemInternalRootPropertyAssignments().size() + " assignments to the type!"); //recreate FxPropertyEdit pe = FxPropertyEdit.createNew("TestAssignmentRemoveProperty1", desc, hint, true, FxMultiplicity.of(0, 1), true, structACL, FxDataType.String1024, new FxString(FxString.EMPTY), true, null, null, null); long id1 = ae.createProperty(testId, pe, "/"); pa = (FxPropertyAssignment) env().getAssignment(id1); long id2 = ae.save(FxPropertyAssignmentEdit.createNew(pa, testType, "TestAssignmentRemoveProperty2", "/"), true); pa = (FxPropertyAssignment) env().getAssignment(id2); ae.save(FxPropertyAssignmentEdit.createNew(pa, testType, "TestAssignmentRemoveProperty3", "/"), true); //recheck testType = env().getType(testId); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty1") .getBaseAssignmentId() == FxAssignment.NO_PARENT); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty2").getBaseAssignmentId() == testType .getAssignment("/TestAssignmentRemoveProperty1").getId()); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty3").getBaseAssignmentId() == testType .getAssignment("/TestAssignmentRemoveProperty2").getId()); ae.removeAssignment(testType.getAssignment("/TestAssignmentRemoveProperty1").getId(), false, false); testType = env().getType(testId); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty2") .getBaseAssignmentId() == FxAssignment.NO_PARENT); assertTrue(testType.getAssignment("/TestAssignmentRemoveProperty3").getBaseAssignmentId() == testType .getAssignment("/TestAssignmentRemoveProperty2").getId()); // test if derived sub-assignments of a derived group are correctly // dereferenced from base assignments if parent group is removed //create base group with assignment FxGroupEdit ge = FxGroupEdit.createNew("TestRemoveGroupBase", desc, hint, true, FxMultiplicity.of(0, 1)); long baseGrpId = ae.createGroup(testId, ge, "/"); FxGroupAssignment baseGrp = (FxGroupAssignment) env().getAssignment(baseGrpId); FxPropertyEdit basePe = FxPropertyEdit.createNew("TestRemoveGroupBaseProperty", desc, hint, true, FxMultiplicity.of(0, 1), true, structACL, FxDataType.String1024, new FxString(FxString.EMPTY), true, null, null, null); long baseAssId = ae.createProperty(testId, basePe, baseGrp.getXPath()); //verify that property assignment is child of group FxPropertyAssignment baseAss = (FxPropertyAssignment) env().getAssignment(baseAssId); assertTrue(baseAss.getParentGroupAssignment().getId() == baseGrp.getId()); //create derived group assignment with derived sub assignments long derivedGrpId = ae.save( FxGroupAssignmentEdit.createNew(baseGrp, env().getType(testId), "TestRemoveGroupDerived", "/"), true); FxGroupAssignment derivedGrp = (FxGroupAssignment) env().getAssignment(derivedGrpId); //verify that group is derived assertTrue(derivedGrp.isDerivedAssignment() && derivedGrp.getBaseAssignmentId() == baseGrp.getId()); //verify that derived group contains derived assignment from base group boolean found = false; long derivedAssId = -1; for (FxAssignment a : derivedGrp.getAssignments()) { if (a.isDerivedAssignment() && a.getBaseAssignmentId() == baseAss.getId()) { found = true; derivedAssId = a.getId(); break; } } assertTrue(found); //remove base group (together with its sub assignments) ae.removeAssignment(baseGrp.getId()); //verify that derived group exists and has been dereferenced assertTrue(!env().getAssignment(derivedGrp.getId()).isDerivedAssignment() && env().getAssignment(derivedGrp.getId()).getBaseAssignmentId() == FxAssignment.NO_PARENT); //verify that derived assignment exists and has been dereferenced assertTrue(!env().getAssignment(derivedAssId).isDerivedAssignment() && env().getAssignment(derivedAssId).getBaseAssignmentId() == FxAssignment.NO_PARENT); te.remove(testId); } /** * Tests overriding the multilanguage setting for a property * * @throws FxNotFoundException on errors * @throws FxInvalidParameterException on errors */ @Test(groups = { "ejb", "structure" }) public void overrideCaptionMultiLangTest() throws FxNotFoundException, FxInvalidParameterException { final FxPropertyAssignmentEdit property = FxPropertyAssignmentEdit.createNew( (FxPropertyAssignment) env().getAssignment("ROOT/CAPTION"), env().getType(FxType.CONTACTDATA), "test", "/"); assertTrue(property.isMultiLang(), "Caption property should be multi-language by default"); if (property.getProperty().mayOverrideMultiLang()) assertTrue(false, "Expected Caption property to be not overridable for this test case!"); try { property.setMultiLang(false); assertTrue(false, "Non-overridable option must not be overridden!"); } catch (FxInvalidParameterException ipe) { //expected } } /** * Tests setting the default language values f. properties * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void defaultValueLanguageTest() throws FxApplicationException { FxPropertyEdit prop = FxPropertyEdit.createNew("testDefLang", new FxString("Test Priority"), new FxString("Priority"), FxMultiplicity.MULT_1_1, env().getACL(ACLCategory.STRUCTURE.getDefaultId()), FxDataType.Number); FxString defML = new FxString(true, "test"); FxString defSL = new FxString(false, "test"); long asId = -1; try { prop.setMultiLang(false); try { prop.setDefaultValue(defML); asId = ae.createProperty(FxType.ROOT_ID, prop, "/"); Assert.fail( "Expected create property to fail with a multilang default value for a singlelang assignment"); } catch (FxRuntimeException e) { //expected } prop.setMultiLang(true); try { prop.setDefaultValue(defSL); asId = ae.createProperty(FxType.ROOT_ID, prop, "/"); Assert.fail( "Expected create property to fail with a singlelang default value for a singlelang assignment"); } catch (FxRuntimeException e) { //expected } prop.setMultiLang(true); prop.setDefaultValue(defML); asId = ae.createProperty(FxType.ROOT_ID, prop, "/"); //this should work } finally { if (asId != -1) ae.removeAssignment(asId); } } /** * AssignmentEngineBean: #getInstanceMultiplicity (implicitly), #getAssignmentInstanceCount, * #getPropertyInstanceCount, #save(FxPropertyEdit), #updateProperty (implicitly), #updatePropertyOptions (implicitly) * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void instanceMultiplicityTest() throws FxApplicationException { SelectListEngine se = EJBLookup.getSelectListEngine(); final String TYPE_NAME = "STRUCTTESTTYPE_" + RandomStringUtils.random(16, true, true); long typeId = createTestTypeAndProp(TYPE_NAME, "TESTPROP", true); long typeIdRefTest = createTestTypeAndProp(TYPE_NAME + "_TWO", "", false); long selListId = -1; try { // test setting some of property attributes (for db update coverage) FxProperty p = env().getProperty("TESTPROP"); FxPropertyEdit pEdit = p.asEditable(); ACL propACL = env().getACL(ACLCategory.SELECTLIST.getDefaultId()); ACL defacl = env().getACL(ACLCategory.STRUCTURE.getDefaultId()); FxSelectListEdit testList = FxSelectListEdit.createNew("Test_selectlist111999", new FxString("test selectlist"), new FxString("test selectlist"), false, defacl, defacl); FxSelectListItemEdit.createNew("ITEM1", defacl, testList, new FxString("item_1"), "value_1", "#000000"); FxSelectListItemEdit.createNew("ITEM2", defacl, testList, new FxString("item_2"), "value_2", "#000000"); selListId = se.save(testList); testList = env().getSelectList(selListId).asEditable(); FxSelectListItem defItem = env().getSelectListItem(testList, "ITEM1"); pEdit.setDataType(FxDataType.SelectOne); pEdit.setReferencedType(env().getType(typeIdRefTest)); pEdit.setUniqueMode(UniqueMode.Type); pEdit.setACL(propACL); pEdit.setReferencedList(env().getSelectList(selListId)); pEdit.setOverrideMultiLang(true); // also needed for assignment tests ae.save(pEdit); p = env().getProperty("TESTPROP"); assertEquals(p.getDataType().getValueClass(), FxSelectOne.class); assertEquals(p.getReferencedType().getId(), typeIdRefTest); assertEquals(p.getUniqueMode(), UniqueMode.Type); assertEquals(p.getACL().getCategory(), ACLCategory.SELECTLIST); assertEquals(p.getReferencedList().getName(), "Test_selectlist111999"); assertTrue(p.mayOverrideMultiLang()); // test property assignments FxPropertyAssignment assProp = (FxPropertyAssignment) env().getAssignment(TYPE_NAME + "/TESTPROP"); FxPropertyAssignmentEdit assEdit = assProp.asEditable(); assEdit.setACL(propACL); assEdit.setMultiLang(true); assEdit.setLabel(new FxString(true, "assignment_label_123456")); assEdit.setDefaultLanguage(FxLanguage.ENGLISH); assEdit.setDefaultValue(new FxSelectOne(true, defItem)); ae.save(assEdit, false); assProp = (FxPropertyAssignment) env().getAssignment(TYPE_NAME + "/TESTPROP"); assertEquals(assProp.getACL(), propACL); assertTrue(assProp.isMultiLang()); assertEquals(assProp.getLabel().toString(), "assignment_label_123456"); assertEquals(assProp.getDefaultLanguage(), FxLanguage.ENGLISH); FxValue val = assProp.getDefaultValue(); assertEquals(val.getValueClass(), FxSelectListItem.class); FxSelectOne selOne = (FxSelectOne) val; FxSelectListItem item = env().getSelectListItem(testList, "ITEM1"); assertEquals(selOne.fromString("" + item.getId()).getData(), "value_1"); } finally { // clean up te.remove(typeId); te.remove(typeIdRefTest); if (selListId != -1) { se.remove(env().getSelectList(selListId)); } } // remaining tests for multiplicity settings etc. typeId = createTestTypeAndProp(TYPE_NAME, "TESTPROP", true); FxPK contentPK1 = createTestContent(typeId, "/TESTPROP", "Testdata 1"); FxPK contentPK2 = createTestContent(typeId, "/TESTPROP", "Testdata 2"); try { FxPropertyAssignmentEdit assEdit = ((FxPropertyAssignment) env().getAssignment(TYPE_NAME + "/TESTPROP")) .asEditable(); FxProperty p = env().getProperty("TESTPROP"); // we should have two assignments for our testprop assertEquals(ae.getAssignmentInstanceCount(assEdit.getId()), 2); // and two instances of testprop were created assertEquals(ae.getPropertyInstanceCount(p.getId()), 2); // alter the multiplicity to 0..2 and set some other properties FxPropertyEdit pEdit = p.asEditable(); pEdit.setOverrideMultiplicity(false); pEdit.setMultiplicity(FxMultiplicity.of(0, 2)); boolean isFulltextIndexed = pEdit.isFulltextIndexed(); if (isFulltextIndexed) { pEdit.setFulltextIndexed(false); } else { pEdit.setFulltextIndexed(true); } boolean mayOverrideACL = pEdit.mayOverrideACL(); if (mayOverrideACL) { pEdit.setOverrideACL(false); } else { pEdit.setOverrideACL(true); } pEdit.setDefaultValue(new FxString(false, "DefaultValue_for_TESTPROP")); ae.save(pEdit); p = env().getProperty("TESTPROP"); assertEquals(p.getMultiplicity().getMin(), 0); assertEquals(p.getMultiplicity().getMax(), 2); assertEquals(p.isFulltextIndexed(), !isFulltextIndexed); assertEquals(p.mayOverrideACL(), !mayOverrideACL); assertEquals(p.getDefaultValue().toString(), "DefaultValue_for_TESTPROP"); // modify the property and implicitly fire #getInstanceMultiplicity via #save pEdit = p.asEditable(); pEdit.setMultiplicity(FxMultiplicity.of(2, 2)); pEdit.setOverrideMultiplicity(false); try { ae.save(pEdit); Assert.fail( "Altering the minimum multiplicity of a property for which content exists should have thrown an exception"); } catch (FxUpdateException e) { // expected } pEdit.setOverrideMultiplicity(true); // reset pEdit.setMultiplicity(FxMultiplicity.of(0, 2)); ae.save(pEdit); assEdit = ((FxPropertyAssignment) env().getAssignment(TYPE_NAME + "/TESTPROP")).asEditable(); assEdit.setMultiplicity(FxMultiplicity.of(0, 2)); ae.save(assEdit, false); // create an additional content instance for the same assignment FxContent co = ce.load(contentPK2); co.setValue("/TESTPROP[2]", new FxString(false, "Testdata 2.2")); ce.save(co); pEdit = env().getProperty("TESTPROP").asEditable(); pEdit.setOverrideMultiplicity(false); pEdit.setMultiplicity(FxMultiplicity.of(0, 1)); try { ae.save(pEdit); Assert.fail( "Changing the maximum property multiplicity for assignment counts > new set maximum should have failed"); } catch (FxUpdateException e) { // expected } pEdit.setMultiplicity(FxMultiplicity.of(3, 3)); try { ae.save(pEdit); Assert.fail( "Changing the minimum property multiplicity for assignment counts > new set minimum should have failed"); } catch (FxUpdateException e) { // expected } // add another content instance pEdit.setOverrideMultiplicity(false); pEdit.setMultiplicity(FxMultiplicity.of(0, 3)); ae.save(pEdit); co = ce.load(contentPK2); co.setValue("/TESTPROP[3]", new FxString(false, "Testdata 2.3")); ce.save(co); pEdit = env().getProperty("TESTPROP").asEditable(); pEdit.setOverrideMultiplicity(false); pEdit.setMultiplicity(FxMultiplicity.of(0, 2)); try { ae.save(pEdit); Assert.fail( "Changing the maximum property multiplicity for assignment counts > new set maximum should have failed"); } catch (FxUpdateException e) { // expected } pEdit.setOverrideMultiplicity(false); // reset pEdit.setMultiplicity(FxMultiplicity.of(0, 3)); ae.save(pEdit); // test multiplicity assignment via #save(FxAssignment) assEdit.setMultiplicity(FxMultiplicity.of(0, 5)); try { ae.save(assEdit, false); Assert.fail( "Overriding the base multiplicity should have failed due to setOverrideMultiplicity(false)"); } catch (FxUpdateException e) { // expected } pEdit.setOverrideMultiplicity(true); // reset pEdit.setMultiplicity(FxMultiplicity.of(0, 3)); ae.save(pEdit); assEdit.setMultiplicity(FxMultiplicity.of(0, 5)); ae.save(assEdit, false); assEdit = ((FxPropertyAssignment) env().getAssignment(TYPE_NAME + "/TESTPROP")).asEditable(); assertEquals(assEdit.getMultiplicity().getMin(), 0); assertEquals(assEdit.getMultiplicity().getMax(), 5); assEdit.setMultiplicity(FxMultiplicity.of(4, 4)); try { ae.save(assEdit, false); Assert.fail( "Assignment of an invalid minimum FxMultiplicity of a property assignment for which content exists should have failed"); } catch (FxUpdateException e) { // expected } // call the #save function again w/ changes to the property's attributes pEdit.setLabel(new FxString(true, FxLanguage.DEFAULT.getId(), "TESTPROP new label")); pEdit.setMultiplicity(FxMultiplicity.of(0, 5)); pEdit.setOverrideMultiplicity(true); pEdit.setHint(new FxString(true, FxLanguage.DEFAULT.getId(), "TESTPROP hint")); ae.save(pEdit); p = env().getProperty(p.getId()); // reload from cache assertEquals(p.getLabel().toString(), "TESTPROP new label"); FxMultiplicity pMult = p.getMultiplicity(); assertEquals(pMult.getMin(), 0); assertEquals(pMult.getMax(), 5); assertEquals(p.getHint().toString(), "TESTPROP hint"); assertTrue(p.mayOverrideBaseMultiplicity()); } finally { // clean up ce.remove(contentPK1); ce.remove(contentPK2); te.remove(typeId); } } /** * AssignmentEngineBean: this method tests #save(FxGroupEdit), #updateGroup(..) [implicitly] * #updateGroupOptions(..) [implicitly] * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void groupAssignmentTests() throws FxApplicationException { long typeId = createTestTypeAndProp("STRUCTTESTTYPE", "TESTPROP", true); // assign the group to our given type and also create a property for the group FxGroupEdit ge = FxGroupEdit.createNew("STRUCTTESTGROUP", new FxString(true, "GROUPDESCR"), new FxString(true, "GROUPHINT"), false, FxMultiplicity.of(0, 1)); ge.setAssignmentGroupMode(GroupMode.OneOf); ae.createGroup(typeId, ge, "/"); ae.createProperty(typeId, FxPropertyEdit .createNew("TESTGROUPPROP", new FxString(true, FxLanguage.ENGLISH, "TESTGROUPPROP"), new FxString(true, FxLanguage.ENGLISH, "TESTPROP"), FxMultiplicity.of(0, 1), env().getACL(ACLCategory.STRUCTURE.getDefaultId()), FxDataType.String1024) .setMultiLang(false), "/STRUCTTESTGROUP"); // create two content instances for our group (within the same assignment) FxPK contentPK = createTestContent(typeId, "/STRUCTTESTGROUP/TESTGROUPPROP", "Testdata 111"); try { // assert group properties ge = env().getGroup("STRUCTTESTGROUP").asEditable(); assertEquals(ge.getName(), "STRUCTTESTGROUP"); assertEquals(ge.getLabel().toString(), "GROUPDESCR"); assertEquals(ge.getHint().toString(), "GROUPHINT"); // make changes to the group and assert them ge.setOverrideMultiplicity(true); ge.setMultiplicity(FxMultiplicity.of(0, 2)); ge.setHint(new FxString(true, "GROUPHINT_NEW")); ge.setLabel(new FxString(true, "GROUPDESCR_NEW")); ge.setName("STRUCTTESTGROUP_NEW"); long groupId = ae.save(ge); ge = env().getGroup("STRUCTTESTGROUP_NEW").asEditable(); assertEquals(ge.getId(), groupId); assertEquals(ge.getLabel().toString(), "GROUPDESCR_NEW"); assertEquals(ge.getHint().toString(), "GROUPHINT_NEW"); assertEquals(ge.getMultiplicity().getMin(), 0); assertEquals(ge.getMultiplicity().getMax(), 2); // increase multiplicity of assignment as well in order to be able to add more content FxGroupAssignmentEdit assEdit = ((FxGroupAssignment) env() .getAssignment("STRUCTTESTTYPE/STRUCTTESTGROUP")).asEditable(); assEdit.getGroupEdit().setOverrideMultiplicity(true); assEdit.setMultiplicity(FxMultiplicity.of(0, 2)); ae.save(assEdit, false); assEdit = ((FxGroupAssignment) env().getAssignment("STRUCTTESTTYPE/STRUCTTESTGROUP")).asEditable(); assertEquals(assEdit.getMultiplicity().getMin(), 0); assertEquals(assEdit.getMultiplicity().getMax(), 2); assertEquals(assEdit.getMode(), GroupMode.OneOf); // create another group/content instance & change the multiplicity settings of both the group and the assignments FxContent co = ce.load(contentPK); co.setValue("/STRUCTTESTGROUP[2]/TESTGROUPPROP[1]", new FxString(false, "Testdata 222")); ce.save(co); ge = env().getGroup("STRUCTTESTGROUP_NEW").asEditable(); ge.setOverrideMultiplicity(false); ge.setMultiplicity(FxMultiplicity.of(0, 1)); try { ae.save(ge); Assert.fail( "Setting the override mult. flag and the maximum group multiplicity to a value less than the number of given content instances should have failed"); } catch (FxUpdateException e) { // expected } ge.setOverrideMultiplicity(false); ge.setMultiplicity(FxMultiplicity.of(3, 3)); try { ae.save(ge); Assert.fail( "Setting the override mult. flag and the minimum group multiplicity to a value greater than the number of given content instances should have failed"); } catch (FxUpdateException e) { // expected } // test multiplicity setting failure code blocks ge.setOverrideMultiplicity(false); // reset ge.setMultiplicity(FxMultiplicity.of(0, 3)); ae.save(ge); co = ce.load(contentPK); co.setValue("/STRUCTTESTGROUP[3]/TESTGROUPPROP[1]", new FxString(false, "Testdata 333")); ce.save(co); ge = env().getGroup("STRUCTTESTGROUP_NEW").asEditable(); ge.setMultiplicity(FxMultiplicity.of(4, 4)); try { ae.save(ge); Assert.fail( "Setting the min. group multiplicity to a value > the current # of the assignment's content instances should have failed"); } catch (FxUpdateException e) { // expected } ge.setMultiplicity(FxMultiplicity.of(0, 2)); try { ae.save(ge); Assert.fail( "Setting the max. group multiplicity to a value < the current # of the assignment's content instances should have failed"); } catch (FxUpdateException e) { // expected } ge.setMultiplicity(FxMultiplicity.of(0, 3)); // reset ge.setOverrideMultiplicity(true); ae.save(ge); // test more group assignment code blocks assEdit = ((FxGroupAssignment) env().getAssignment("STRUCTTESTTYPE/STRUCTTESTGROUP")).asEditable(); assEdit.setLabel(new FxString(true, "ASSIGNMENTLABEL_XX123456")); assEdit.setHint(new FxString(true, "ASSIGNMENTHINT_XX123456")); assEdit.setXPath("/STRUCTTESTGROUP_NEW_PATH"); assEdit.setMode(GroupMode.AnyOf); ae.save(assEdit, false); assEdit = ((FxGroupAssignment) env().getAssignment("STRUCTTESTTYPE/STRUCTTESTGROUP_NEW_PATH")) .asEditable(); assertEquals(assEdit.getLabel().toString(), "ASSIGNMENTLABEL_XX123456"); assertEquals(assEdit.getHint().toString(), "ASSIGNMENTHINT_XX123456"); assertEquals(assEdit.getMode(), GroupMode.AnyOf); // set the group mode and the alias assEdit.setMode(GroupMode.OneOf); try { ae.save(assEdit, false); Assert.fail( "Changing the a group's mode from AnyOf to OneOf for existing content instance should have failed"); } catch (FxUpdateException e) { // expected } assEdit.setMode(GroupMode.AnyOf); assEdit.setAlias("STRUCTTESTGROUP_NEW_ALIAS"); ae.save(assEdit, false); assEdit = ((FxGroupAssignment) env().getAssignment("STRUCTTESTTYPE/STRUCTTESTGROUP_NEW_ALIAS")) .asEditable(); assertEquals(assEdit.getAlias(), "STRUCTTESTGROUP_NEW_ALIAS"); // disable the assignment assEdit.setEnabled(false); ae.save(assEdit, true); assEdit = ((FxGroupAssignment) env().getAssignment("STRUCTTESTTYPE/STRUCTTESTGROUP_NEW_ALIAS")) .asEditable(); assertTrue(!assEdit.isEnabled()); assertEquals(assEdit.getDefaultMultiplicity(), 1); // test setting the default multiplicity to a higher value than the current assEdit.setDefaultMultiplicity(assEdit.getMultiplicity().getMax() + 1); ae.save(assEdit, false); assEdit = ((FxGroupAssignment) env().getAssignment("STRUCTTESTTYPE/STRUCTTESTGROUP_NEW_ALIAS")) .asEditable(); assertEquals(assEdit.getDefaultMultiplicity(), assEdit.getMultiplicity().getMax()); // TODO: (remaining code blocks) test set position, updategroupassignmentoptions, updategroupoptions, systeminternal flag (prop and group) } finally { // clean up ce.remove(contentPK); te.remove(typeId); } } /** * AssignmentEngineBean: tests #removeProperty(long propertyId) * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void removePropertyTests() throws FxApplicationException { long typeId1 = createTestTypeAndProp("REMOVALTEST1", "", false); long typeId2 = createTestTypeAndProp("REMOVALTEST2", "", false); // create properties ae.createProperty(typeId1, FxPropertyEdit.createNew( // for type1 "REMOVETESTPROP1", new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP1"), new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP1"), FxMultiplicity.of(0, 2), env().getACL(ACLCategory.STRUCTURE.getDefaultId()), FxDataType.String1024).setMultiLang(false), "/"); ae.createProperty(typeId1, FxPropertyEdit.createNew( // for type1 "REMOVETESTPROP2", new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP2"), new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP2"), FxMultiplicity.of(0, 2), env().getACL(ACLCategory.STRUCTURE.getDefaultId()), FxDataType.String1024).setMultiLang(false), "/"); // create derived assignments ae.save(FxPropertyAssignmentEdit.reuse("REMOVALTEST1/REMOVETESTPROP1", "REMOVALTEST2", "/", "REMOVETESTPROP1_ALIAS"), false); // type2 ae.save(FxPropertyAssignmentEdit.reuse("REMOVALTEST1/REMOVETESTPROP2", "REMOVALTEST2", "/", "REMOVETESTPROP2_ALIAS"), false); // type2 try { // tests go here List<FxPropertyAssignment> assignments; FxProperty prop1, prop2; prop1 = env().getProperty("REMOVETESTPROP1"); assignments = env().getPropertyAssignments(prop1.getId(), true); assertEquals(assignments.size(), 2); assertTrue(findDerivedPropInList(assignments, "REMOVETESTPROP1_ALIAS")); prop2 = env().getProperty("REMOVETESTPROP2"); assignments = env().getPropertyAssignments(prop2.getId(), true); assertEquals(assignments.size(), 2); assertTrue(findDerivedPropInList(assignments, "REMOVETESTPROP2_ALIAS")); // try to remove a property which doesn't exist try { ae.removeProperty(999999); Assert.fail("Removing a non-existing property should throw an exception!"); } catch (FxNotFoundException e) { // expected } // remove prop1 and assert that both the property and the alias were removed ae.removeProperty(prop1.getId()); assertTrue(!findInPropAssignments("REMOVETESTPROP1")); assertTrue(!findInPropAssignments("REMOVETESTPROP1_ALIAS")); // create content for the remaining assignments and the original properties FxContent co = ce.initialize(typeId2); co.setValue("/REMOVETESTPROP2_ALIAS", new FxString(false, "content for prop2_alias")); FxPK contentPK1 = ce.save(co); co = ce.initialize(typeId1); co.setValue("/REMOVETESTPROP2", new FxString(false, "content for prop2")); FxPK contentPK2 = ce.save(co); // remove the property and assert that the corresponding content was removed as well ae.removeProperty(prop2.getId()); assertTrue(!findInPropAssignments("REMOVETESTPROP2")); assertTrue(!findInPropAssignments("REMOVETESTPROP2_ALIAS")); co = ce.load(contentPK1); try { co.getValue("/REMOVETESTPROP2_ALIAS"); Assert.fail("Loading a content value for a non-existing Xpath should have failed"); } catch (Exception e) { // expected } co = ce.load(contentPK2); try { co.getValue("/REMOVETESTPROP2"); Assert.fail("Loading a content value for a non-existing Xpath should have failed"); } catch (Exception e) { // expected } } finally { // clean up ce.removeForType(typeId1); ce.removeForType(typeId2); te.remove(typeId1); te.remove(typeId2); } } /** * AssignmentEngineBean: tests #removeGroup(long groupId) * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void removeGroupTests() throws FxApplicationException { createTestTypeAndProp("REMOVALTEST1", "", false); createTestTypeAndProp("REMOVALTEST2", "", false); FxType t1, t2; FxGroup g1, g2; FxProperty p1, p2; FxPK contentPK1 = null; FxPK contentPK2 = null; t1 = env().getType("REMOVALTEST1"); t2 = env().getType("REMOVALTEST2"); // create groups ae.createGroup(t1.getId(), FxGroupEdit.createNew("REMOVETESTGROUP1", new FxString(true, FxLanguage.ENGLISH, "REMOVETESTGROUP1"), new FxString(true, FxLanguage.ENGLISH, "HINT1"), true, FxMultiplicity.of(0, 2)), "/"); ae.createGroup(t1.getId(), FxGroupEdit.createNew("REMOVETESTGROUP2", new FxString(true, FxLanguage.ENGLISH, "REMOVETESTGROUP2"), new FxString(true, FxLanguage.ENGLISH, "HINT2"), true, FxMultiplicity.of(0, 2)), "/"); g1 = env().getGroup("REMOVETESTGROUP1"); g2 = env().getGroup("REMOVETESTGROUP2"); // create properties ae.createProperty(t1.getId(), FxPropertyEdit.createNew( // for type1 "REMOVETESTPROP1", new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP1"), new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP1"), FxMultiplicity.of(0, 2), env().getACL(ACLCategory.STRUCTURE.getDefaultId()), FxDataType.String1024).setMultiLang(false), "/REMOVETESTGROUP1"); ae.createProperty(t1.getId(), FxPropertyEdit.createNew( // for type1 "REMOVETESTPROP2", new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP2"), new FxString(true, FxLanguage.ENGLISH, "REMOVETESTPROP2"), FxMultiplicity.of(0, 2), env().getACL(ACLCategory.STRUCTURE.getDefaultId()), FxDataType.String1024).setMultiLang(false), "/REMOVETESTGROUP2"); p1 = env().getProperty("REMOVETESTPROP1"); p2 = env().getProperty("REMOVETESTPROP2"); // create derived assignments List<FxGroupAssignment> gAssigns = env().getGroupAssignments(g1.getId(), true); assertTrue(gAssigns.size() == 1); ae.save(FxGroupAssignmentEdit.createNew(gAssigns.get(0), t2, "REMOVETESTGROUP1_ALIAS", "/"), false); ae.save(FxPropertyAssignmentEdit.reuse("REMOVALTEST1/REMOVETESTGROUP1/REMOVETESTPROP1", "REMOVALTEST2", "/REMOVETESTGROUP1_ALIAS", "REMOVETESTPROP1_ALIAS"), false); // type2 gAssigns = env().getGroupAssignments(g1.getId(), true); assertTrue(gAssigns.size() == 2); gAssigns = env().getGroupAssignments(g2.getId(), true); assertTrue(gAssigns.size() == 1); ae.save(FxGroupAssignmentEdit.createNew(gAssigns.get(0), t2, "REMOVETESTGROUP2_ALIAS", "/"), false); ae.save(FxPropertyAssignmentEdit.reuse("REMOVALTEST1/REMOVETESTGROUP2/REMOVETESTPROP2", "REMOVALTEST2", "/REMOVETESTGROUP2_ALIAS", "REMOVETESTPROP2_ALIAS"), false); // type2 gAssigns = env().getGroupAssignments(g2.getId(), true); assertTrue(gAssigns.size() == 2); try { // tests go here List<FxPropertyAssignment> pAssigns; gAssigns = env().getGroupAssignments(g1.getId(), true); pAssigns = env().getPropertyAssignments(p1.getId(), true); assertTrue(gAssigns.size() == 2); assertTrue(findDerivedGroupInList(gAssigns, "REMOVETESTGROUP1_ALIAS")); assertTrue(findDerivedPropInList(pAssigns, "REMOVETESTPROP1_ALIAS")); gAssigns = env().getGroupAssignments(g2.getId(), true); pAssigns = env().getPropertyAssignments(p2.getId(), true); assertTrue(gAssigns.size() == 2); assertTrue(findDerivedGroupInList(gAssigns, "REMOVETESTGROUP2_ALIAS")); assertTrue(findDerivedPropInList(pAssigns, "REMOVETESTPROP2_ALIAS")); // remove a group which doesn't exist try { ae.removeGroup(999999); Assert.fail("Removing a non-existant group should have failed"); } catch (FxNotFoundException e) { // expected } // remove one of the above created groups ae.removeGroup(g2.getId()); gAssigns = env().getGroupAssignments(g2.getId(), true); assertTrue(gAssigns.size() == 0); // prop 2 should also be a goner pAssigns = env().getPropertyAssignments(p2.getId(), true); assertTrue(pAssigns.size() == 0); // create content for the remaining group / properties FxContent co = ce.initialize(t1.getId()); co.setValue("/REMOVETESTGROUP1/REMOVETESTPROP1", new FxString(false, "group 1/ prop 1 content")); contentPK1 = ce.save(co); co = ce.initialize(t2.getId()); co.setValue("/REMOVETESTGROUP1_ALIAS/REMOVETESTPROP1_ALIAS", new FxString(false, "group 1 alias / prop 1 alias content")); contentPK2 = ce.save(co); ae.removeGroup(g1.getId()); try { co = ce.load(contentPK1); try { co.getValue("/REMOVETESTGROUP1/REMOVETESTPROP1"); Assert.fail( "Loading content values for removed props / groups should have thrown an exception"); } catch (Exception e) { // expected } } catch (Exception e) { // might fail here already } try { co = ce.load(contentPK2); try { co.getValue("/REMOVETESTGROUP1_ALIAS/REMOVETESTPROP1_ALIAS"); Assert.fail( "Loading content values for removed props / groups should have thrown an exception"); } catch (Exception e) { // expected } } catch (Exception e) { // might fail here already } gAssigns = env().getGroupAssignments(g1.getId(), true); assertTrue(gAssigns.size() == 0); // prop 2 should also be a goner pAssigns = env().getPropertyAssignments(p1.getId(), true); assertTrue(pAssigns.size() == 0); } finally { if (contentPK1 != null) ce.remove(contentPK1); if (contentPK2 != null) ce.remove(contentPK2); te.remove(t2.getId()); te.remove(t1.getId()); } } /** * AssignmentEngineBean: Test changing a property's alias * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void propertyAliasChangeTest() throws FxApplicationException { long typeId = createTestTypeAndProp("ALIASTEST", "", false); // add properties ae.createProperty(typeId, FxPropertyEdit.createNew("PROP1", new FxString(true, "PROP1"), new FxString(true, ""), FxMultiplicity.of(0, 5), env().getACL("Default Structure ACL"), FxDataType.String1024), "/"); ae.createProperty(typeId, FxPropertyEdit.createNew("PROP2", new FxString(true, "PROP2"), new FxString(true, ""), FxMultiplicity.of(0, 5), env().getACL("Default Structure ACL"), FxDataType.String1024), "/"); ae.createProperty(typeId, FxPropertyEdit.createNew("PROP3", new FxString(true, "PROP3"), new FxString(true, ""), FxMultiplicity.of(0, 5), env().getACL("Default Structure ACL"), FxDataType.String1024), "/"); // create content FxPK contentPK1 = createTestContent(typeId, "/PROP1", "Testdata1_1", "Testdata1_2"); FxPK contentPK2 = createTestContent(typeId, "/PROP2", "Testdata2_1", "Testdata2_2"); FxPK contentPK3 = createTestContent(typeId, "/PROP3", "Testdata3_1", "Testdata3_2"); // change the property assignments' aliases try { FxPropertyAssignmentEdit ed; ed = getPropAssEd("ALIASTEST/PROP1").setAlias("PROP1ALIAS"); ae.save(ed, true); ed = getPropAssEd("ALIASTEST/PROP2").setAlias("PROP2ALIAS"); ae.save(ed, true); ed = getPropAssEd("ALIASTEST/PROP3").setAlias("PROP3ALIAS"); ae.save(ed, true); // assert that both the aliases have changed, the original XPath assignments do not exist anymore and also that // the relevant content instances' paths have changed assertFalse(env().assignmentExists("ALIASTEST/PROP1")); assertFalse(env().assignmentExists("ALIASTEST/PROP2")); assertFalse(env().assignmentExists("ALIASTEST/PROP3")); assertTrue(env().assignmentExists("ALIASTEST/PROP1ALIAS")); assertTrue(env().assignmentExists("ALIASTEST/PROP2ALIAS")); assertTrue(env().assignmentExists("ALIASTEST/PROP3ALIAS")); FxContent co; co = ce.load(contentPK1); try { co.getValue("ALIASTEST/PROP1"); } catch (Exception e) { // expected } try { co.getValue("ALIASTEST/PROP1[2]"); } catch (Exception e) { // expected } assertEquals(co.getValue("ALIASTEST/PROP1ALIAS[1]").toString(), "Testdata1_1"); assertEquals(co.getValue("ALIASTEST/PROP1ALIAS[2]").toString(), "Testdata1_2"); co = ce.load(contentPK2); try { co.getValue("ALIASTEST/PROP2"); } catch (Exception e) { // expected } try { co.getValue("ALIASTEST/PROP2[2]"); } catch (Exception e) { // expected } assertEquals(co.getValue("ALIASTEST/PROP2ALIAS[1]").toString(), "Testdata2_1"); assertEquals(co.getValue("ALIASTEST/PROP2ALIAS[2]").toString(), "Testdata2_2"); co = ce.load(contentPK3); try { co.getValue("ALIASTEST/PROP3"); } catch (Exception e) { // expected } try { co.getValue("ALIASTEST/PROP3[2]"); } catch (Exception e) { // expected } assertEquals(co.getValue("ALIASTEST/PROP3ALIAS").toString(), "Testdata3_1"); assertEquals(co.getValue("ALIASTEST/PROP3ALIAS[2]").toString(), "Testdata3_2"); } finally { for (FxPK pk : ce.getPKsForType(typeId, true)) { ce.remove(pk); } te.remove(typeId); } } /** * AssignmentEngineBean: Test changing a group's alias * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void groupAliasChangeTest() throws FxApplicationException { /** * Structure: * ALIASTEST * --PROP1 * --GROUP1 * --PROP2 * --GROUP2 * --PROP3 */ long typeId = createTestTypeAndProp("ALIASTEST", "", false); // add more properties ae.createProperty(typeId, FxPropertyEdit.createNew("PROP1", new FxString(true, "PROP1"), new FxString(true, ""), FxMultiplicity.of(0, 5), env().getACL("Default Structure ACL"), FxDataType.String1024), "/"); ae.createGroup(typeId, FxGroupEdit.createNew("GROUP1", new FxString(true, "GROUP1"), new FxString(true, ""), true, FxMultiplicity.of(0, 2)), "/"); ae.createProperty(typeId, FxPropertyEdit.createNew("PROP2", new FxString(true, "PROP2"), new FxString(true, ""), FxMultiplicity.of(0, 2), env().getACL("Default Structure ACL"), FxDataType.String1024), "/GROUP1"); ae.createGroup(typeId, FxGroupEdit.createNew("GROUP2", new FxString(true, "GROUP2"), new FxString(true, ""), true, FxMultiplicity.of(0, 2)), "/GROUP1"); ae.createProperty(typeId, FxPropertyEdit.createNew("PROP3", new FxString(true, "PROP3"), new FxString(true, ""), FxMultiplicity.of(0, 2), env().getACL("Default Structure ACL"), FxDataType.String1024), "/GROUP1/GROUP2"); // create content FxPK contentPK1 = createTestContent(typeId, "/PROP1", "Testdata1_1", "Testdata1_2"); FxPK contentPK2 = createTestContent(typeId, "/GROUP1/PROP2", "Testdata2_1", "Testdata2_2"); FxPK contentPK3 = createTestContent(typeId, "/GROUP1/GROUP2/PROP3", "Testdata3_1", "Testdata3_2"); try { // change group aliases FxGroupAssignmentEdit ga; ga = getGroupAssEd("ALIASTEST/GROUP1").setAlias("GROUP1ALIAS"); ae.save(ga, true); ga = getGroupAssEd("ALIASTEST/GROUP1ALIAS/GROUP2").setAlias("group2alias"); // diff. case ae.save(ga, true); assertFalse(env().assignmentExists("ALIASTEST/GROUP1")); assertFalse(env().assignmentExists("ALIASTEST/GROUP1/GROUP2")); assertTrue(env().assignmentExists("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS")); // try to load the respective content 2 - proves functionality for all other contents FxContent co; co = ce.load(contentPK2); try { co.getValue("ALIASTEST/GROUP1/PROP2"); } catch (Exception e) { // expected } try { co.getValue("ALIASTEST/GROUP1/PROP2[2]"); } catch (Exception e) { // expected } assertEquals(co.getValue("ALIASTEST/GROUP1ALIAS/PROP2").toString(), "Testdata2_1"); assertEquals(co.getValue("ALIASTEST/GROUP1ALIAS/PROP2[2]").toString(), "Testdata2_2"); // make changes to the property aliases FxPropertyAssignmentEdit pa; pa = getPropAssEd("ALIASTEST/PROP1").setAlias("PROP1ALIAS"); ae.save(pa, true); pa = getPropAssEd("ALIASTEST/GROUP1ALIAS/PROP2").setAlias("PROP2ALIAS"); ae.save(pa, true); pa = getPropAssEd("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS/PROP3").setAlias("PROP3ALIAS"); ae.save(pa, true); assertFalse(env().assignmentExists("ALIASTEST/PROP1")); assertFalse(env().assignmentExists("ALIASTEST/GROUP1ALIAS/PROP2")); assertFalse(env().assignmentExists("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS/PROP3")); assertTrue(env().assignmentExists("ALIASTEST/PROP1ALIAS")); assertTrue(env().assignmentExists("ALIASTEST/GROUP1ALIAS/PROP2ALIAS")); assertTrue(env().assignmentExists("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS/PROP3ALIAS")); // test w/ content 1 & 3 co = ce.load(contentPK1); try { co.getValue("ALIASTEST/PROP1"); } catch (Exception e) { // expected } try { co.getValue("ALIASTEST/PROP1[2]"); } catch (Exception e) { // expected } assertEquals(co.getValue("ALIASTEST/PROP1ALIAS").toString(), "Testdata1_1"); assertEquals(co.getValue("ALIASTEST/PROP1ALIAS[2]").toString(), "Testdata1_2"); co = ce.load(contentPK3); try { co.getValue("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS/PROP3"); } catch (Exception e) { // expected } try { co.getValue("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS/PROP3[2]"); } catch (Exception e) { // expected } assertEquals(co.getValue("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS/PROP3ALIAS").toString(), "Testdata3_1"); assertEquals(co.getValue("ALIASTEST/GROUP1ALIAS/GROUP2ALIAS/PROP3ALIAS[2]").toString(), "Testdata3_2"); } finally { for (FxPK pk : ce.getPKsForType(typeId, true)) { ce.remove(pk); } te.remove(typeId); } } /** * AssignmentEngineBean: test creating props / groups with immedately assigned aliases * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void createAliasedElementsTest() throws FxApplicationException { long typeId = createTestTypeAndProp("ALIASASSIGN", "", false); // add a prop and groups ae.createProperty(typeId, FxPropertyEdit.createNew("PROP1", new FxString(true, "PROP1"), new FxString(true, ""), FxMultiplicity.of(0, 5), env().getACL("Default Structure ACL"), FxDataType.String1024), "/", "prop1alias"); ae.createGroup(typeId, FxGroupEdit.createNew("GROUP1", new FxString(true, "GROUP1"), new FxString(true, ""), true, FxMultiplicity.of(0, 2)), "/", "group1alias"); try { assertTrue(env().assignmentExists("ALIASASSIGN/PROP1ALIAS")); assertFalse(env().assignmentExists("ALIASASSIGN/PROP1")); assertTrue(env().assignmentExists("ALIASASSIGN/GROUP1ALIAS")); assertFalse(env().assignmentExists("ALIASASSIGN/GROUP1")); // create aliased sub-group ae.createGroup(typeId, FxGroupEdit.createNew("GROUP2", new FxString(true, "group2"), new FxString(true, ""), true, FxMultiplicity.of(0, 2)), "/group1alias", "group2alias"); assertTrue(env().assignmentExists("ALIASASSIGN/GROUP1ALIAS/GROUP2ALIAS")); assertFalse(env().assignmentExists("ALIASASSIGN/GROUP1ALIAS/GROUP2")); } finally { te.remove(typeId); } } /** * Tests setting generic structure options for groups / properties * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void testGenericStructureOptions() throws FxApplicationException { long typeId = createTestTypeAndProp("OPTTEST", "", false); FxPropertyEdit pEd = FxPropertyEdit.createNew("PROP1OPTTEST", new FxString(true, "PROP1"), new FxString(true, ""), FxMultiplicity.of(0, 5), env().getACL("Default Structure ACL"), FxDataType.String1024); pEd.setOption("OPT.1P", false, "OPT 1 value"); pEd.setOption("OPT.2P", true, false); ae.createProperty(typeId, pEd, "/"); FxGroupEdit gEd = FxGroupEdit.createNew("GROUP1OPTTEST", new FxString(true, "GROUP1"), new FxString(true, ""), true, FxMultiplicity.of(0, 2)); gEd.setOption("OPT.1G", false, "OPT 1 value"); gEd.setOption("OPT.2G", true, false); ae.createGroup(typeId, gEd, "/"); try { FxProperty p = env().getProperty("PROP1OPTTEST"); FxGroup g = env().getGroup("GROUP1OPTTEST"); assertEquals(p.getOption("OPT.1P").getValue(), "OPT 1 value"); assertEquals(p.getOption("OPT.2P").getIntValue(), 0); assertFalse(p.getOption("OPT.1P").isOverridable()); assertTrue(p.getOption("OPT.2P").isOverridable()); assertEquals(g.getOption("OPT.1G").getValue(), "OPT 1 value"); assertEquals(g.getOption("OPT.2G").getIntValue(), 0); assertFalse(g.getOption("OPT.1G").isOverridable()); assertTrue(g.getOption("OPT.2G").isOverridable()); // create an assignment and check whether the group options are "passed along" FxGroupAssignmentEdit ga = FxGroupAssignmentEdit.createNew( (FxGroupAssignment) getEnvironment().getAssignment("OPTTEST/GROUP1OPTTEST"), getEnvironment().getType("OPTTEST"), "GROUP1OPTTESTDER", "/"); long aId = ae.save(ga, false); FxGroupAssignment gass = (FxGroupAssignment) getEnvironment().getAssignment("OPTTEST/GROUP1OPTTESTDER"); assertEquals(gass.getOption("OPT.1G").getValue(), "OPT 1 value"); assertEquals(gass.getOption("OPT.2G").getIntValue(), 0); assertFalse(gass.getOption("OPT.1G").isOverridable()); assertTrue(gass.getOption("OPT.2G").isOverridable()); ae.removeAssignment(aId); } finally { te.remove(typeId); } } @Test(groups = { "ejb", "structure" }) public void typeAclAssignmentMultiplicity() throws FxApplicationException { final String base = "typeAclAssignmentMultiplicity"; final List<Long> typeIds = Lists.newArrayList(); try { typeIds.add(getTypeEngine().save(FxTypeEdit.createNew(base + "_1").setMultipleContentACLs(false))); assertEquals(getEnvironment().getAssignment(base + "_1/ACL").getMultiplicity(), FxMultiplicity.MULT_1_1); // derive without changing the multiple ACLs setting typeIds.add(getTypeEngine().save(FxTypeEdit.createNew(base + "_1_2", base + "_1"))); assertEquals(getEnvironment().getAssignment(base + "_1_2/ACL").getMultiplicity(), FxMultiplicity.MULT_1_1); typeIds.add(getTypeEngine() .save(FxTypeEdit.createNew(base + "_1_2_3", base + "_1_2").setMultipleContentACLs(true))); assertEquals(getEnvironment().getAssignment(base + "_1_2_3/ACL").getMultiplicity(), FxMultiplicity.MULT_1_N); typeIds.add(getTypeEngine().save(FxTypeEdit.createNew(base + "_2").setMultipleContentACLs(true))); assertEquals(getEnvironment().getAssignment(base + "_2/ACL").getMultiplicity(), FxMultiplicity.MULT_1_N); } finally { Collections.reverse(typeIds); for (Long typeId : typeIds) { getTypeEngine().remove(typeId); } } } @Test(groups = { "ejb", "structure" }) public void typeFastCreateTest() throws FxApplicationException { // creates a type through FxTypeEdit's add... methods final FxTypeEdit type = FxTypeEdit.createNew("typeFastCreateTest").save(); FxPK pk = null; try { final FxEnvironment env = CacheAdmin.getEnvironment(); type.addProperty("string", FxDataType.String1024).setMultiplicity(FxMultiplicity.MULT_1_1).save(); type.addGroup("group1").setLabel(new FxString(true, "group label")).save(); type.addProperty("group1/groupstring", FxDataType.String1024); type.addGroup("group1/group2"); type.addProperty("group1/group2/group2string", FxDataType.String1024); type.addProperty("number", FxDataType.Number); type.addSelectListProperty("country", env.getSelectList(FxSelectList.COUNTRIES), false); type.addReferenceProperty("documentref", env.getType(FxType.DOCUMENTFILE)); FxPropertyAssignmentEdit fxpae = type.addProperty("test", FxDataType.HTML); fxpae.setMultiplicity(FxMultiplicity.MULT_0_1).save(); // try to create some content... final FxContent content = EJBLookup.getContentEngine().initialize(type.getId()); content.setValue("/string", "a value"); content.setValue("/group1/groupstring", "group value"); content.setValue("/group1/group2/group2string", "group 2 value"); content.setValue("/number", 123); pk = content.save().getPk(); type.save(); try { fxpae.setMultiplicity(FxMultiplicity.MULT_1_1).save(); fail("the modification of minimumMultiplicity should not be possible"); } catch (FxUpdateException e) { // pass } try { type.addProperty("test2", FxDataType.HTML).setMultiplicity(FxMultiplicity.MULT_1_1).save(); fail("the modification of minimumMultiplicity should not be possible"); } catch (FxUpdateException e) { // pass } } finally { if (pk != null) { EJBLookup.getContentEngine().remove(pk); } te.remove(type.getId()); } } /** * Test setting / loading structural options for types and derived types * * @throws FxApplicationException on errors */ @Test(groups = { "ejb", "structure" }) public void typeStructureOptionsTest() throws FxApplicationException { FxTypeEdit type = null; FxTypeEdit typeDer = null; FxType t1 = null; FxType t1der = null; try { type = FxTypeEdit.createNew("STRUCTOPTTEST"); type.setOption("OPTION_A", "a value"); // overridable, not inherited type.setOption("OPTION_B", "another value", false, true); // non-overridable, inherited type.setOption("OPTION_BOOL_A", true); // overridable, not inherited type.setOption("OPTION_BOOL_B", false, false, true); // non-overridable, inherited type.setOption("OPTION_C", "C", true, true); // overridable, inherited type = type.save(); // create a derived type FxTypeEdit.createNew("STRUCTOPTTESTDERIVED", type.getId()).save(); // safety reload t1 = getEnvironment().getType("STRUCTOPTTEST"); t1der = getEnvironment().getType("STRUCTOPTTESTDERIVED"); Assert.assertEquals(t1.getOption("OPTION_A").getValue(), "a value"); Assert.assertTrue(t1.getOption("OPTION_A").isOverridable()); Assert.assertFalse(t1.getOption("OPTION_A").getIsInherited()); Assert.assertEquals(t1.getOption("OPTION_B").getValue(), "another value"); Assert.assertFalse(t1.getOption("OPTION_B").isOverridable()); Assert.assertTrue(t1.getOption("OPTION_B").getIsInherited()); Assert.assertEquals(t1.getOption("OPTION_BOOL_A").isValueTrue(), true); Assert.assertTrue(t1.getOption("OPTION_BOOL_A").isOverridable()); Assert.assertFalse(t1.getOption("OPTION_BOOL_A").getIsInherited()); Assert.assertEquals(t1.getOption("OPTION_BOOL_B").isValueTrue(), false); Assert.assertFalse(t1.getOption("OPTION_BOOL_B").isOverridable()); Assert.assertTrue(t1.getOption("OPTION_BOOL_B").getIsInherited()); Assert.assertEquals(t1.getOption("OPTION_C").getValue(), "C"); Assert.assertTrue(t1.getOption("OPTION_C").isOverridable()); Assert.assertTrue(t1.getOption("OPTION_C").getIsInherited()); Assert.assertEquals(t1der.getOption("OPTION_B").getValue(), "another value"); Assert.assertFalse(t1der.getOption("OPTION_BOOL_B").isValueTrue()); Assert.assertEquals(t1der.getOption("OPTION_C").getValue(), "C"); // try to set the overridable and the non-overridable options typeDer = getEnvironment().getType("STRUCTOPTTESTDERIVED").asEditable(); typeDer.setOption("OPTION_C", "C NEW"); try { typeDer.setOption("OPTION_B", "new value"); Assert.fail("It should not be possible to set values for un-overridable, inherited options"); } catch (FxApplicationException e) { // expected } typeDer.save(); t1der = getEnvironment().getType("STRUCTOPTTESTDERIVED"); Assert.assertEquals(t1der.getOption("OPTION_C").getValue(), "C NEW"); } finally { if (t1der != null) te.remove(t1der.getId()); if (t1 != null) te.remove(t1.getId()); } } /** * Test setting mime types for DOCUMENTFILE and its derived types * * @throws FxApplicationException on errors * * @since 3.1 */ @Test(groups = { "ejb", "structure" }) public void mimeTypeTest() throws FxApplicationException { try { FxType docRoot = getEnvironment().getType(FxType.DOCUMENTFILE); te.save(FxTypeEdit.createNew("MIMETESTER", docRoot.getId())); FxType testType = getEnvironment().getType("MIMETESTER"); // we should have unknown/unknown Assert.assertEquals(testType.getMimeType().getMimeTypes().size(), 1); Assert.assertTrue(testType.getMimeType().contains("unknown/unknown")); // replace with video/flv te.save(testType.asEditable().setMimeType(new FxMimeTypeWrapper("video/flv"))); testType = getEnvironment().getType("MIMETESTER"); // we should have video/flv Assert.assertEquals(testType.getMimeType().getMimeTypes().size(), 1); Assert.assertTrue(testType.getMimeType().contains("video/flv")); // clean up te.remove(testType.getId()); // test setting a mime type f. a type not derived from DocumentFile te.save(FxTypeEdit.createNew("MIMETESTER")); testType = getEnvironment().getType("MIMETESTER"); try { testType.asEditable().setMimeType(new FxMimeTypeWrapper("foo/bar")); Assert.fail( "Setting a mime type for an FxType which is not derived from \"DOCUMENTFILE\" should have failed"); } catch (Exception e) { // do nothing } } finally { if (getEnvironment().typeExists("MIMETESTER")) te.remove(getEnvironment().getType("MIMETESTER").getId()); } } /** * Tests inheritance / overridable options of FxStructureOptions f. assignments * --> Tests propagation to derived assignments of base assignments * * @throws FxApplicationException on errors * @since 3.1.1 */ @Test(groups = { "ejb", "structure", "optinherit" }) public void assignmentOptionInheritanceTest() throws FxApplicationException { long baseTypeId = -1, derTypeId = -1, sepTypeId = -1; long propID1 = -1, propID2 = -1, propID3 = -1, propID4 = -1, groupID1 = -1, groupID2 = -1; final String TEST1 = "OPTINHERITANCE"; final String TEST1DER = "DEROPTINHERITANCE"; try { // create a test type & a prop(assignment) baseTypeId = createTestTypeAndProp(TEST1, "proptest1", true); // retrieve assignment and create a few structure options // PROPERTY assignment options // opt1 - overridable, inherited // opt2 - overridable, inherited (to test several) // opt3 - overridable, not inherited // opt4 - not overridable, inherited // opt5 - not overridable, not inherited // GROUP assignment options // groupopt1 - overridable, inherited // groupopt2 - not overridable, inherited // groupopt3 - overridable, not inherited FxPropertyAssignmentEdit propTest1 = ((FxPropertyAssignment) env().getAssignment(TEST1 + "/PROPTEST1")) .asEditable(); List<FxStructureOption> options = new ArrayList<FxStructureOption>(5); options.add(new FxStructureOption("opt1", true, true, true, "VAL1")); options.add(new FxStructureOption("opt2", true, true, true, "VAL2")); options.add(new FxStructureOption("opt3", true, true, false, "VAL3")); options.add(new FxStructureOption("opt4", false, true, true, "VAL4")); options.add(new FxStructureOption("opt5", false, true, false, "VAL5")); propTest1.setOptions(options); ae.save(propTest1, false); // create a group and options FxGroupEdit group = FxGroupEdit.createNew("TESTGROUP1", new FxString(true, "TESTGROUP1"), new FxString(true, ""), true, FxMultiplicity.MULT_0_1); ae.createGroup(baseTypeId, group, "/"); FxGroupAssignmentEdit groupTest1 = ((FxGroupAssignment) env().getAssignment(TEST1 + "/TESTGROUP1")) .asEditable(); options = new ArrayList<FxStructureOption>(3); options.add(new FxStructureOption("groupopt1", true, true, true, "G1")); options.add(new FxStructureOption("groupopt2", false, true, true, "G2")); options.add(new FxStructureOption("groupopt3", true, true, false, "G3")); groupTest1.setOptions(options); ae.save(groupTest1, false); // reload orig assignments propTest1 = ((FxPropertyAssignment) env().getAssignment(TEST1 + "/PROPTEST1")).asEditable(); groupTest1 = ((FxGroupAssignment) env().getAssignment(TEST1 + "/TESTGROUP1")).asEditable(); Assert.assertEquals(propTest1.getOptions().size(), 5); Assert.assertEquals(groupTest1.getOptions().size(), 3); // create a derived type - only option assignments having isInherited=true should be passed on derTypeId = te.save(FxTypeEdit.createNew(TEST1DER, TEST1)); FxPropertyAssignmentEdit propTest1Der = ((FxPropertyAssignment) env() .getAssignment(TEST1DER + "/PROPTEST1")).asEditable(); propID1 = propTest1Der.getId(); FxGroupAssignmentEdit groupTest1Der = ((FxGroupAssignment) env() .getAssignment(TEST1DER + "/TESTGROUP1")).asEditable(); groupID1 = groupTest1Der.getId(); // assertions for inherited options final List<FxStructureOption> derPropOptions = propTest1Der.getOptions(); final List<FxStructureOption> derGroupOptions = groupTest1Der.getOptions(); Assert.assertEquals(derPropOptions.size(), 3); Assert.assertEquals(derGroupOptions.size(), 2); // prop Assert.assertTrue(propTest1Der.hasOption("OPT1")); Assert.assertTrue(propTest1Der.hasOption("OPT2")); Assert.assertTrue(propTest1Der.hasOption("OPT4")); // not overridable // group Assert.assertTrue(groupTest1Der.hasOption("GROUPOPT1")); Assert.assertTrue(groupTest1Der.hasOption("GROUPOPT2")); // test setting prop options propTest1Der.setOption("OPT1", "VAL1NEW"); propTest1Der.setOption("OPT2", "VAL2NEW"); try { propTest1Der.setOption("OPT4", "VAL4NEW"); Assert.fail( "Setting an inherited property assignment option which cannot be overridden should have failed"); } catch (FxInvalidParameterException e) { // ignore } ae.save(propTest1Der, false); propTest1Der = ((FxPropertyAssignment) env().getAssignment(TEST1DER + "/PROPTEST1")).asEditable(); Assert.assertEquals(propTest1Der.getOption("OPT1").getValue(), "VAL1NEW"); Assert.assertEquals(propTest1Der.getOption("OPT2").getValue(), "VAL2NEW"); // test setting group options groupTest1Der.setOption("GROUPOPT1", "G1NEWVAL"); try { groupTest1Der.setOption("GROUPOPT2", "G2NEWVAL"); Assert.fail( "Setting an inherited group assignment option which cannot be overridden should have failed"); } catch (FxInvalidParameterException e) { // ignore } ae.save(groupTest1Der, false); groupTest1Der = ((FxGroupAssignment) env().getAssignment(TEST1DER + "/TESTGROUP1")).asEditable(); Assert.assertEquals(groupTest1Der.getOption("GROUPOPT1").getValue(), "G1NEWVAL"); // test option inheritance propagation for property assignments: // add 2 more inherited options to propTest1Der --> should be propagated to propTest1 in the derived type propTest1.setOption("INHERITOPT1", true, true, true); propTest1.setOption("INHERITOPT2", false, true, "1234"); ae.save(propTest1, false); // reload proptest1der propTest1Der = ((FxPropertyAssignment) env().getAssignment(TEST1DER + "/PROPTEST1")).asEditable(); Assert.assertEquals(propTest1Der.getOptions().size(), 5); Assert.assertTrue(propTest1Der.hasOption("INHERITOPT1")); Assert.assertTrue(propTest1Der.hasOption("INHERITOPT2")); // and we should still have the "original" options Assert.assertTrue(propTest1Der.hasOption("OPT1")); Assert.assertTrue(propTest1Der.hasOption("OPT2")); Assert.assertTrue(propTest1Der.hasOption("OPT4")); // test option inheritance propagation for group assignments: // add 2 more inherited options to groupTest1Der --> should be propagated to groupTest1 in the derived type groupTest1.setOption("GROUPINHERITOPT1", true, true, true); groupTest1.setOption("GROUPINHERITOPT2", false, true, "5678"); ae.save(groupTest1, false); // reload groupTest2 groupTest1Der = ((FxGroupAssignment) env().getAssignment(TEST1DER + "/TESTGROUP1")).asEditable(); Assert.assertEquals(groupTest1Der.getOptions().size(), 4); Assert.assertTrue(groupTest1Der.hasOption("GROUPINHERITOPT1")); Assert.assertTrue(groupTest1Der.hasOption("GROUPINHERITOPT2")); // and we should still have the "original" options Assert.assertTrue(groupTest1Der.hasOption("GROUPOPT1")); Assert.assertTrue(groupTest1Der.hasOption("GROUPOPT2")); // ALIASED assignments --> copies all options (functionality = fx <=3.1) // 1. aliased assignment in a derived type // Notice: aliasing a property to a derived type's group will have the same outcome) propTest1 = ((FxPropertyAssignment) env().getAssignment(TEST1 + "/PROPTEST1")).asEditable(); // reload propID3 = ae.save( FxPropertyAssignmentEdit.createNew(propTest1, env().getType(TEST1DER), "TEST1ALIAS", "/"), false); FxPropertyAssignment aliasTest = (FxPropertyAssignment) env().getAssignment(TEST1DER + "/TEST1ALIAS"); options = aliasTest.getOptions(); Assert.assertEquals(propTest1.getOptions().size(), 7); // assert orig. no. of options Assert.assertEquals(options.size(), 7); // all options, including those w/ inherited == false Assert.assertTrue(FxStructureOption.hasOption("OPT1", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT2", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT3", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT4", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT5", options)); Assert.assertTrue(FxStructureOption.hasOption("INHERITOPT1", options)); Assert.assertTrue(FxStructureOption.hasOption("INHERITOPT2", options)); // 2. aliased assignment in a separate type sepTypeId = createTestTypeAndProp("SEPARATE", null, false); propID4 = ae.save( FxPropertyAssignmentEdit.createNew(propTest1, env().getType("SEPARATE"), "TEST1ALIAS2", "/"), false); FxPropertyAssignment aliasTest2 = (FxPropertyAssignment) env().getAssignment("SEPARATE/TEST1ALIAS2"); options = aliasTest2.getOptions(); Assert.assertEquals(options.size(), 7); // all options, including those w/ inherited == false Assert.assertTrue(FxStructureOption.hasOption("OPT1", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT2", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT3", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT4", options)); Assert.assertTrue(FxStructureOption.hasOption("OPT5", options)); Assert.assertTrue(FxStructureOption.hasOption("INHERITOPT1", options)); Assert.assertTrue(FxStructureOption.hasOption("INHERITOPT2", options)); } finally { // rem. derived assignments first if (propID4 != -1) ae.removeAssignment(propID4); if (propID3 != -1) ae.removeAssignment(propID3); if (propID2 != -1) ae.removeAssignment(propID2); if (groupID2 != -1) ae.removeAssignment(groupID2); if (propID1 != -1) ae.removeAssignment(propID1); if (groupID1 != -1) ae.removeAssignment(groupID1); // remove types if (sepTypeId != -1) te.remove(sepTypeId); if (derTypeId != -1) te.remove(derTypeId); if (baseTypeId != -1) te.remove(baseTypeId); } } @Test(groups = { "ejb", "structure" }) public void testAutoPropertyNames() throws FxApplicationException { // ensure that auto property names work for more than 10 (where subtle sorting/ID generation issues can occur) final long typeId = createTestTypeAndProp("AUTO_PROP_TEST", null, false); final FxTypeEdit type = CacheAdmin.getEnvironment().getType(typeId).asEditable(); try { for (int i = 0; i < 15; i++) { final FxGroupAssignmentEdit group = type.addGroup("group_" + i); final FxPropertyAssignmentEdit pa = type .addProperty(XPathElement.stripType(group.getXPath()) + "/autoprop", FxDataType.String1024); assertTrue(pa.getId() > 0); assertTrue(i == 0 || !"autoprop".equalsIgnoreCase(pa.getProperty().getName()), "Unique property name not set"); } } finally { te.remove(typeId); } } /** * Helper method to find the alias in a list of property assignments * * @param list the list of FxPropertyAssignments * @param name the name of the property (alias) * @return returns true if the alias was found */ private boolean findDerivedPropInList(List<FxPropertyAssignment> list, String name) { for (FxPropertyAssignment a : list) { if (name.equalsIgnoreCase(a.getAlias()) || name.equalsIgnoreCase(a.getDisplayName())) return true; } return false; } /** * Helper method to find the alias in a list of group assignments * * @param list the list of FxGroupAssignments * @param name the name of the group (alias) * @return returns true if the alias was found */ private boolean findDerivedGroupInList(List<FxGroupAssignment> list, String name) { for (FxGroupAssignment a : list) { if (name.equalsIgnoreCase(a.getAlias()) || name.equalsIgnoreCase(a.getDisplayName())) return true; } return false; } /** * Helper method to assert existance of a property assignment. * * @param alias the alias or name of the property * @return returns true if the name / alias was found in the list of property assignments */ private boolean findInPropAssignments(String alias) { for (FxPropertyAssignment a : env().getPropertyAssignments(true)) { if (alias.equals(a.getAlias()) || alias.equals(a.getDisplayName())) { return true; } } return false; } /** * Creates a test type and property * * @param typeName the name/label for the type to be created * @param propertyName the name/label of the property which should be created * @param createProp if set to true, it will create a property called "TESTPROP" assigned to the type * @return the ids of the test type (long[0]) and its property (long[1]) * @throws FxApplicationException on errors */ private long createTestTypeAndProp(String typeName, String propertyName, boolean createProp) throws FxApplicationException { long typeId = te.save(FxTypeEdit.createNew(typeName, new FxString(typeName), env().getACL(ACLCategory.STRUCTURE.getDefaultId()))); if (createProp) { ae.createProperty(typeId, FxPropertyEdit .createNew(propertyName, new FxString(true, FxLanguage.ENGLISH, propertyName), new FxString(true, FxLanguage.ENGLISH, "TESTPROP"), FxMultiplicity.of(0, 1), env().getACL(ACLCategory.STRUCTURE.getDefaultId()), FxDataType.String1024) .setMultiLang(false), "/"); } return typeId; } /** * Creates a test content instance for the "STRUCTTESTTYPE" and its assigned "TESTPROP" * * @param typeId the id of the type for which the content instance will be created * @param propertyPath the property's XPath * @param testData a String value for test data * @return FxPK the content instance PK * @throws FxApplicationException on errors */ private FxPK createTestContent(long typeId, String propertyPath, String... testData) throws FxApplicationException { final FxContent co = ce.initialize(typeId); int coCount = 1; for (String tData : testData) { final FxString data = new FxString(false, tData); co.setValue(propertyPath + "[" + coCount++ + "]", data); } return ce.save(co); } /** * @param xPath the assignment's XPath * @return returns an FxPropertyAssignmentEdit instance */ private FxPropertyAssignmentEdit getPropAssEd(String xPath) { return ((FxPropertyAssignment) env().getAssignment(xPath)).asEditable(); } /** * @param xPath the assignment's XPath * @return returns an FxGroupAssignmentEdit instance */ private FxGroupAssignmentEdit getGroupAssEd(String xPath) { return ((FxGroupAssignment) env().getAssignment(xPath)).asEditable(); } /** * @return FxEnvironment */ private FxEnvironment env() { return getEnvironment(); } }