/* * Copyright (C) 2005-2012 BetaCONCEPT Limited * * This file is part of Astroboa. * * Astroboa 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 3 of the License, or * (at your option) any later version. * * Astroboa 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. * * You should have received a copy of the GNU Lesser General Public License * along with Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.console.jsf.space; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.faces.application.FacesMessage; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.ContentObject; import org.betaconceptframework.astroboa.api.model.Space; import org.betaconceptframework.astroboa.api.model.io.FetchLevel; import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType; import org.betaconceptframework.astroboa.api.service.ContentService; import org.betaconceptframework.astroboa.api.service.SpaceService; import org.betaconceptframework.astroboa.console.commons.ContentObjectUIWrapper; import org.betaconceptframework.astroboa.console.commons.ContentObjectUIWrapperFactory; import org.betaconceptframework.astroboa.console.jsf.DynamicUIAreaPageComponent; import org.betaconceptframework.astroboa.console.jsf.PageController; import org.betaconceptframework.astroboa.console.jsf.space.SpaceItem.SpaceItemType; import org.betaconceptframework.astroboa.console.seam.SeamEventNames; import org.betaconceptframework.astroboa.console.security.LoggedInRepositoryUser; import org.betaconceptframework.astroboa.model.factory.CmsRepositoryEntityFactory; import org.betaconceptframework.ui.jsf.AbstractUIBean; import org.betaconceptframework.ui.jsf.utility.JSFUtilities; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Factory; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; import org.jboss.seam.core.Events; import org.jboss.seam.international.LocaleSelector; import org.richfaces.event.DropEvent; @Name("sharedSpaceNavigation") @Scope(ScopeType.CONVERSATION) /** * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public class SharedSpaceNavigation extends AbstractUIBean { private static final long serialVersionUID = 1L; private ContentService contentService; private ContentObjectUIWrapperFactory contentObjectUIWrapperFactory; private LoggedInRepositoryUser loggedInRepositoryUser; private PageController pageController; private SpaceService spaceService; private Space currentSpace; private String selectedSpaceId; private String selectedObjectId; private String newSpaceName; @Out(required=false) private List<Space> breadCrumbForSharedSpaces ; private SpaceItemLocalizeLabelComparator spaceItemLocalizeLabelComparator = new SpaceItemLocalizeLabelComparator(); @In private LocaleSelector localeSelector; @Out(required=false) private List<SpaceItem> sharedSpaceItems; private CmsRepositoryEntityFactory cmsRepositoryEntityFactory; public String showSharedSpace_UIAction(){ return showSpace_UIAction(spaceService.getOrganizationSpace()); } public String showSpace_UIAction(Space space) { currentSpace = space; createBreadCrumbSpaces(); createSpaceItems(); return pageController.loadPageComponentInDynamicUIArea(DynamicUIAreaPageComponent.SHARED_SPACE_NAVIGATOR.getDynamicUIAreaPageComponent()); } public String showSpace_UIAction(String spaceId) { return showSpace_UIAction(spaceService.getSpace(spaceId, ResourceRepresentationType.SPACE_INSTANCE, FetchLevel.ENTITY_AND_CHILDREN)); } @Factory("breadCrumbForSharedSpaces") public void getBreadCrumbForSharedSpaces(){ if (currentSpace == null) currentSpace = spaceService.getOrganizationSpace(); createBreadCrumbSpaces(); } private void createBreadCrumbSpaces() { breadCrumbForSharedSpaces = new ArrayList<Space>(); breadCrumbForSharedSpaces.add(currentSpace); Space tempSpace = currentSpace.getParent(); while(tempSpace != null){ breadCrumbForSharedSpaces.add(tempSpace); tempSpace = tempSpace.getParent(); } Collections.reverse(breadCrumbForSharedSpaces); } @Factory("sharedSpaceItems") public void getSharedSpaceItems(){ if (currentSpace == null) currentSpace = spaceService.getOrganizationSpace(); createSpaceItems(); } private void createSpaceItems() { sharedSpaceItems = new ArrayList<SpaceItem>(); if (currentSpace == null) { return; } //Load all child spaces List<Space> childSpaces = currentSpace.getChildren(); if (CollectionUtils.isNotEmpty(childSpaces)){ for (Space childSpace: childSpaces){ addNewSpaceItemForSpace(childSpace); } } //Load all contentObject references List<String> contentObjectReferencesInCurrentSpace = currentSpace.getContentObjectReferences(); if (CollectionUtils.isNotEmpty(contentObjectReferencesInCurrentSpace)) { for (String contentObjectReference : contentObjectReferencesInCurrentSpace) { ContentObject contentObject = contentService.getContentObject(contentObjectReference, ResourceRepresentationType.CONTENT_OBJECT_INSTANCE, FetchLevel.ENTITY, null, null, false); if (contentObject != null) { addNewSpaceIemForObject(contentObject); } else { logger.warn("A non existent object with id: '" + contentObjectReference + "' is referenced in space with internal name: '" + currentSpace.getName() + "' and localized name: '" + currentSpace.getLocalizedLabelForLocale(localeSelector.getLocaleString())); } } } sortSpaceItems(); } private void sortSpaceItems() { Collections.sort(sharedSpaceItems, spaceItemLocalizeLabelComparator); } private void addNewSpaceItemForSpace(Space childSpace) { SpaceItem spaceItem = new SpaceItem(); spaceItem.setType(SpaceItemType.SPACE); spaceItem.setLocalizedLabel(childSpace.getAvailableLocalizedLabel(JSFUtilities.getLocaleAsString())); spaceItem.setSpaceItemObject(childSpace); spaceItem.setSpaceService(spaceService); sharedSpaceItems.add(spaceItem); } private void addNewSpaceIemForObject(ContentObject object) { SpaceItem spaceItem = new SpaceItem(); spaceItem.setType(SpaceItemType.CONTENTOBJECT); spaceItem.setSpaceItemObject(contentObjectUIWrapperFactory.getInstance(object)); sharedSpaceItems.add(spaceItem); } public void removeObjectFromFolder(){ try{ List<String> contentObjectReferences = currentSpace.getContentObjectReferences(); if (CollectionUtils.isNotEmpty(contentObjectReferences) && contentObjectReferences.contains(selectedObjectId)){ contentObjectReferences.remove(selectedObjectId); spaceService.save(currentSpace); // recreate spaceItems createSpaceItems(); } } catch(Exception e){ JSFUtilities.addMessage(null, "application.unknown.error.message", null, FacesMessage.SEVERITY_WARN); logger.error("",e); return; } } public void deleteSpace(){ if (StringUtils.isNotBlank(selectedSpaceId)) { try { for (SpaceItem spaceItem : sharedSpaceItems) { if (spaceItem.getType().equals(SpaceItem.SpaceItemType.SPACE)) { Space space = (Space) spaceItem.getSpaceItemObject(); if (space.getId().equals(selectedSpaceId)) { spaceService.deleteSpace(space.getId()); /* Removing space from List does not work * because list stores proxy spaces and not space objects * Either the list must be iterated to find the space to remove or we may reset the list in order to force * lazy loading to initialize list again with the expense of one more query * List<Space> children = currentSpace.getChildren(); if (CollectionUtils.isNotEmpty(children)) children.remove(space); */ currentSpace.setChildren(null); createSpaceItems(); // the event allows the folder tree to be updated too Events.instance().raiseEvent(SeamEventNames.RELOAD_SPACE_TREE_NODE, currentSpace.getId()); break; } } } } catch(Exception e){ JSFUtilities.addMessage(null, "application.unknown.error.message", null , FacesMessage.SEVERITY_WARN); logger.error("",e); return; } } else { JSFUtilities.addMessage(null, "application.unknown.error.message", null , FacesMessage.SEVERITY_WARN); logger.error("Could not rename space. Either the space id or the new space name is empty"); } } public void addNewSpace_UIAction(){ try{ if (currentSpace == null) currentSpace = spaceService.getOrganizationSpace(); Space newSpace = cmsRepositoryEntityFactory.newSpace(); newSpace.setOwner(loggedInRepositoryUser.getRepositoryUser()); newSpace.addLocalizedLabel(localeSelector.getLocaleString(), JSFUtilities.getLocalizedMessage("space.administration.new.space.default.localized.label", null)); currentSpace.addChild(newSpace); spaceService.save(newSpace); addNewSpaceItemForSpace(newSpace); sortSpaceItems(); // the event allows the folder tree to be updated too Events.instance().raiseEvent(SeamEventNames.RELOAD_SPACE_TREE_NODE, currentSpace.getId()); } catch(Exception e){ JSFUtilities.addMessage(null, "application.unknown.error.message", null, FacesMessage.SEVERITY_ERROR); logger.error("",e); return; } } public void changeSpaceLocalizedLabel(){ if (StringUtils.isNotBlank(selectedSpaceId) && StringUtils.isNotBlank(newSpaceName)) { try { for (SpaceItem spaceItem : sharedSpaceItems) { if (spaceItem.getType().equals(SpaceItem.SpaceItemType.SPACE)) { Space space = (Space) spaceItem.getSpaceItemObject(); if (space.getId().equals(selectedSpaceId)) { space.addLocalizedLabel(localeSelector.getLocaleString(), newSpaceName); space = spaceService.save(space); spaceItem.setLocalizedLabel(newSpaceName); sortSpaceItems(); // the event allows the folder tree to be updated too Events.instance().raiseEvent(SeamEventNames.RELOAD_SPACE_TREE_NODE, currentSpace.getId()); break; } } } } catch(Exception e){ JSFUtilities.addMessage(null, "application.unknown.error.message", null , FacesMessage.SEVERITY_WARN); logger.error("",e); return; } } else { JSFUtilities.addMessage(null, "application.unknown.error.message", null , FacesMessage.SEVERITY_WARN); logger.error("Could not rename space. Either the space id or the new space name is empty"); } } public void handleDraggedAndDroppedItem_Listener(DropEvent dropEvent) { if (dropEvent.getDragType().equals("contentObject")) { linkDraggedAndDroppedObject(dropEvent); } else if (dropEvent.getDragType().equals("sharedSpace")) { moveDraggedAndDroppedSpace(dropEvent); } } public void moveDraggedAndDroppedSpace(DropEvent dropEvent) { try { LazyLoadingSpaceTreeNodeRichFaces nodeToBeMoved = (LazyLoadingSpaceTreeNodeRichFaces) dropEvent.getDragValue(); LazyLoadingSpaceTreeNodeRichFaces newParentNode = (LazyLoadingSpaceTreeNodeRichFaces) dropEvent.getDropValue(); Space spaceToBeMoved = nodeToBeMoved.getSpace(); Space newSpaceParent = newParentNode.getSpace(); // prevent moving a space into itsself or into its children if (!newParentNode.getIdentifier().startsWith(nodeToBeMoved.getIdentifier())) { String oldSpaceParentId = spaceToBeMoved.getParent().getId(); List<String> spaceIdList = new ArrayList<String>(); spaceIdList.add(oldSpaceParentId); spaceIdList.add(newSpaceParent.getId()); spaceToBeMoved.setParent(newSpaceParent); spaceService.save(spaceToBeMoved); // the event allows the folder tree to be updated Events.instance().raiseEvent(SeamEventNames.RELOAD_SPACE_TREE_NODES, spaceIdList); // we will also update the folder tab in the case that the user is currently viewing // the parent of the space to be moved, the space to be moved or the new parent node if ( spaceToBeMoved.getId().equals(currentSpace.getId()) || oldSpaceParentId.equals(currentSpace.getId()) || newSpaceParent.getId().equals(currentSpace.getId()) ) { createBreadCrumbSpaces(); createSpaceItems(); } JSFUtilities.addMessage(null, "space.administration.move.success", null, FacesMessage.SEVERITY_INFO); } else { JSFUtilities.addMessage(null, "space.administration.move.cannotMoveSpaceIntoItselfOrIntoChildSpace", null, FacesMessage.SEVERITY_WARN); logger.warn("Could not move the space into itself or into a child space."); } } catch (Exception e) { JSFUtilities.addMessage(null, "space.administration.move.failure", null, FacesMessage.SEVERITY_INFO); logger.warn("failed to move space", e); } } public void linkDraggedAndDroppedObject(DropEvent dropEvent) { try { ContentObjectUIWrapper objectToBeCopiedInSpace = (ContentObjectUIWrapper) dropEvent.getDragValue(); LazyLoadingSpaceTreeNodeRichFaces spaceTreeNodeIntoWhichObjectIsCopied = (LazyLoadingSpaceTreeNodeRichFaces) dropEvent.getDropValue(); Space spaceIntoWhichObjectIsCopied = spaceTreeNodeIntoWhichObjectIsCopied.getSpace(); List<String> spaceIdList = new ArrayList<String>(); spaceIdList.add(spaceIntoWhichObjectIsCopied.getId()); spaceIntoWhichObjectIsCopied.addContentObjectReference(objectToBeCopiedInSpace.getContentObject().getId()); spaceService.save(spaceIntoWhichObjectIsCopied); // the event allows the folder tree to be updated Events.instance().raiseEvent(SeamEventNames.RELOAD_SPACE_TREE_NODES, spaceIdList); // we will also update the folder tab in the case that the user is currently viewing // the space into which we copied the object if (currentSpace != null && spaceIntoWhichObjectIsCopied.getId().equals(currentSpace.getId())) { createBreadCrumbSpaces(); createSpaceItems(); } JSFUtilities.addMessage(null, "space.administration.linkObject.success", null, FacesMessage.SEVERITY_INFO); } catch (Exception e) { JSFUtilities.addMessage(null, "space.administration.linkObject.failure", null, FacesMessage.SEVERITY_WARN); logger.warn("Could not link the dragged object into space.", e); } } public void setContentService(ContentService contentService) { this.contentService = contentService; } public void setContentObjectUIWrapperFactory( ContentObjectUIWrapperFactory contentObjectUIWrapperFactory) { this.contentObjectUIWrapperFactory = contentObjectUIWrapperFactory; } public void setLoggedInRepositoryUser( LoggedInRepositoryUser loggedInRepositoryUser) { this.loggedInRepositoryUser = loggedInRepositoryUser; } public void setSpaceService(SpaceService spaceService) { this.spaceService = spaceService; } public Space getCurrentSpace() { return currentSpace; } public void setSelectedSpaceId(String selectedSpaceId) { this.selectedSpaceId = selectedSpaceId; } public void setNewSpaceName(String newSpaceName) { this.newSpaceName = newSpaceName; } public void setCmsRepositoryEntityFactory( CmsRepositoryEntityFactory cmsRepositoryEntityFactory) { this.cmsRepositoryEntityFactory = cmsRepositoryEntityFactory; } public void setSelectedObjectId(String selectedObjectId) { this.selectedObjectId = selectedObjectId; } }