/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * For further information about Alkacon Software, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.db; import org.opencms.file.CmsObject; import org.opencms.file.CmsProject; import org.opencms.file.CmsResource; import org.opencms.file.CmsResource.CmsResourceUndoMode; import org.opencms.file.types.CmsResourceTypePlain; import org.opencms.main.CmsException; import org.opencms.main.OpenCms; import org.opencms.test.OpenCmsTestCase; import org.opencms.test.OpenCmsTestProperties; import org.opencms.util.CmsUUID; import junit.framework.Test; /** * Tests the URL name mapping facilities of OpenCms.<p> * * @since 8.0.0 */ public class TestUrlNameMapping extends OpenCmsTestCase { /** The counter used for generating new file names. */ private static int m_fileCounter; /** * Test constructor.<p> * * @param arg0 */ public TestUrlNameMapping(String arg0) { super(arg0); } /** * Returns the test suite.<p> * * @return the test suite */ public static Test suite() { OpenCmsTestProperties.initialize(org.opencms.test.AllTests.TEST_PROPERTIES_PATH); return generateSetupTestWrapper(TestUrlNameMapping.class, "systemtest", "/"); } /** * Creates a new file and returns it.<p> * * @return the new file * @throws Exception if something goes wrong */ public CmsResource createFile() throws Exception { CmsResource result = getCmsObject().createResource( "/file" + m_fileCounter++, CmsResourceTypePlain.getStaticTypeId()); return result; } /** * Helper method for getting a CMS context set to the Online project.<p> * * @return a {@link CmsObject} with the project set to the Online project * * @throws Exception if something goes wrong */ public CmsObject getOnlineCmsObject() throws Exception { CmsObject result = OpenCms.initCmsObject(getCmsObject()); CmsProject onlineProject = getCmsObject().readProject(CmsProject.ONLINE_PROJECT_ID); result.getRequestContext().setCurrentProject(onlineProject); return result; } /** * Tests that when a not-new resource is deleted and published, its URL name mappings are also deleted.<p> * * @throws Exception if something goes wrong */ public void testDeleteChanged() throws Exception { CmsObject cms = getCmsObject(); CmsObject onlineCms = getOnlineCmsObject(); String baseName = "testDeleteChanged"; String changedName = "testDeleteChanged2"; String otherName = "testDeleteChanged3"; CmsResource res = createFile(); CmsResource res2 = createFile(); addMapping(changedName, res); addMapping(baseName, res); addMapping(otherName, res2); publish(); delete(res); assertEquals(res.getStructureId(), onlineCms.readIdForUrlName(baseName)); assertEquals(baseName, onlineCms.readBestUrlName( res.getStructureId(), onlineCms.getRequestContext().getLocale(), OpenCms.getLocaleManager().getDefaultLocales())); assertEquals(res.getStructureId(), cms.readIdForUrlName(baseName)); assertEquals(baseName, readBestUrlName(cms, res.getStructureId())); publish(); assertNull(onlineCms.readIdForUrlName(baseName)); assertNull(onlineCms.readIdForUrlName(changedName)); assertNull(readBestUrlName(onlineCms, res.getStructureId())); assertNull(cms.readIdForUrlName(baseName)); assertNull(readBestUrlName(cms, res.getStructureId())); assertEquals(otherName, readBestUrlName(onlineCms, res2.getStructureId())); assertEquals(res2.getStructureId(), onlineCms.readIdForUrlName(otherName)); } String readBestUrlName(CmsObject cms, CmsUUID structureId) throws CmsException { return cms.readBestUrlName( structureId, cms.getRequestContext().getLocale(), OpenCms.getLocaleManager().getDefaultLocales()); } /** * Tests that when a new resource is deleted, its URL name mapping is also deleted.<p> * * @throws Exception if something goes wrong */ public void testDeleteNew() throws Exception { CmsObject cms = getCmsObject(); String baseName = "testDeleteNew"; CmsResource res = createFile(); addMapping(baseName, res); delete(res); assertNull(cms.readIdForUrlName(baseName)); assertNull(readBestUrlName(cms, res.getStructureId())); } /** * Tests mapping the same URL name to multiple ids.<p> * * @throws Exception if something goes wrong */ public void testMultipleIdMapping() throws Exception { CmsObject cms = getCmsObject(); String baseName = "testMultipleIdMapping"; CmsResource res1 = createFile(); CmsResource res2 = createFile(); String name = baseName; CmsUUID id1 = res1.getStructureId(); CmsUUID id2 = res2.getStructureId(); String returnedName1 = addMapping(name, res1); String returnedName2 = addMapping(name, res2); publish(); assertTrue(returnedName2.contains(returnedName1)); assertFalse(returnedName2.equals(returnedName1)); assertEquals(returnedName1, readBestUrlName(cms, id1)); assertEquals(returnedName2, readBestUrlName(cms, id2)); } /** * Tests mapping multiple names to the same resource.<p> * * @throws Exception if something goes wrong */ public void testMultipleNameMapping() throws Exception { CmsObject cms = getCmsObject(); String baseName = "testMultipleNameMapping"; String name1 = baseName + 1; String name2 = baseName + 2; CmsResource res = createFile(); String returnedName1 = addMapping(name1, res); publish(); String returnedName2 = addMapping(name2, res); publish(); assertEquals(name1, returnedName1); assertEquals(name2, returnedName2); assertEquals(name2, readBestUrlName(cms, res.getStructureId())); assertEquals(res.getStructureId(), cms.readIdForUrlName(name1)); assertEquals(res.getStructureId(), cms.readIdForUrlName(name2)); } /** * Tests that an URL name that has not been published will be overwritten by a new URL name.<p> * * @throws Exception if something goes wrong */ public void testOverwrite() throws Exception { CmsObject cms = getCmsObject(); String baseName = "testOverwrite"; String changedName = baseName + "Foo"; CmsResource res = createFile(); addMapping(baseName, res); addMapping(changedName, res); assertEquals(changedName, readBestUrlName(cms, res.getStructureId())); assertNull(cms.readIdForUrlName(baseName)); assertEquals(res.getStructureId(), cms.readIdForUrlName(changedName)); } /** * Tests publishing the URL name mappings of a resource.<p> * * @throws Exception if something goes wrong */ public void testPublish() throws Exception { CmsObject onlineCms = getOnlineCmsObject(); String baseName = "testPublish"; CmsResource res = createFile(); publish(); addMapping(baseName, res); assertNull(onlineCms.readIdForUrlName(baseName)); assertNull(readBestUrlName(onlineCms, res.getStructureId())); publish(); assertEquals(baseName, readBestUrlName(onlineCms, res.getStructureId())); assertEquals(res.getStructureId(), onlineCms.readIdForUrlName(baseName)); } /** * Tests adding a single url name in the Offline project.<p> * * @throws Exception if something goes wrong */ public void testSimpleMapping() throws Exception { CmsObject cms = getCmsObject(); String name = "testSimpleMapping"; CmsResource res = createFile(); String returnedName = addMapping(name, res); publish(); assertEquals(name, returnedName); String foundName = readBestUrlName(cms, res.getStructureId()); assertEquals(name, foundName); CmsUUID foundId = cms.readIdForUrlName(name); assertEquals(res.getStructureId(), foundId); } /** * Tests that when the changes of a resource are undone, its unpublished URL name mapping will be removed.<p> * * @throws Exception if something goes wrong */ public void testUndo() throws Exception { CmsObject cms = getCmsObject(); CmsObject onlineCms = getOnlineCmsObject(); String baseName = "testUndo"; String changedName = baseName + "Foo"; CmsResource res = createFile(); addMapping(baseName, res); publish(); addMapping(changedName, res); cms.lockResource(cms.getSitePath(res)); cms.undoChanges(cms.getSitePath(res), CmsResourceUndoMode.MODE_UNDO_MOVE_CONTENT); cms.unlockResource(cms.getSitePath(res)); assertEquals(res.getStructureId(), cms.readIdForUrlName(baseName)); assertEquals(baseName, readBestUrlName(cms, res.getStructureId())); assertNull(onlineCms.readIdForUrlName(changedName)); } /** * Helper method for adding a resource mapping.<p> * * @param name the mapping name to be used * @param res the resource to which the * * @return the URL name which has actually been mapped * @throws Exception */ protected String addMapping(String name, CmsResource res) throws Exception { CmsObject cms = getCmsObject(); // touch the resource so that we can publish it and its URL name mappings later touch(res); String result = cms.writeUrlNameMapping(name, res.getStructureId(), "en"); return result; } /** * Helper method for deleting a resource.<p> * * @param res the resource to delete * @throws Exception if something goes wrong */ protected void delete(CmsResource res) throws Exception { CmsObject cms = getCmsObject(); String sitePath = cms.getSitePath(res); cms.lockResource(sitePath); getCmsObject().deleteResource(sitePath, CmsResource.DELETE_PRESERVE_SIBLINGS); try { cms.unlockResource(sitePath); } catch (CmsException e) { // ignore } } /** * Helper method for publishing the current project.<p> * @throws Exception */ protected void publish() throws Exception { OpenCms.getPublishManager().publishProject(getCmsObject()); OpenCms.getPublishManager().waitWhileRunning(); } /** * Changes a resource's "last modified" time to the current time.<p> * * @param res the resource which should be touched * * @throws Exception if something goes wrong */ protected void touch(CmsResource res) throws Exception { CmsObject cms = getCmsObject(); String path = cms.getSitePath(res); cms.lockResource(path); cms.setDateLastModified(path, System.currentTimeMillis(), false); cms.unlockResource(cms.getSitePath(res)); } }