/* * Copyright 2013 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.kie.workbench.common.screens.explorer.client.widgets; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.annotation.PostConstruct; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.Window; import org.guvnor.common.services.project.builder.model.BuildResults; import org.guvnor.common.services.project.builder.service.BuildService; import org.guvnor.common.services.project.context.ProjectContext; import org.guvnor.common.services.project.context.ProjectContextChangeEvent; import org.guvnor.common.services.project.model.Package; import org.guvnor.common.services.project.model.Project; import org.guvnor.common.services.shared.validation.model.ValidationMessage; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.security.shared.api.identity.User; import org.kie.workbench.common.screens.explorer.client.utils.URLHelper; import org.kie.workbench.common.screens.explorer.client.utils.Utils; import org.kie.workbench.common.screens.explorer.client.widgets.branches.BranchChangeHandler; import org.kie.workbench.common.screens.explorer.client.widgets.navigator.Explorer; import org.kie.workbench.common.screens.explorer.client.widgets.tagSelector.TagChangedEvent; import org.kie.workbench.common.screens.explorer.model.FolderItem; import org.kie.workbench.common.screens.explorer.model.FolderItemType; import org.kie.workbench.common.screens.explorer.model.FolderListing; import org.kie.workbench.common.screens.explorer.model.ProjectExplorerContent; import org.kie.workbench.common.screens.explorer.service.ExplorerService; import org.kie.workbench.common.services.shared.preferences.ApplicationPreferences; import org.kie.workbench.common.services.shared.validation.ValidationService; import org.kie.workbench.common.widgets.client.popups.validation.ValidationPopup; import org.kie.workbench.common.widgets.client.resources.i18n.CommonConstants; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.VFSService; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.docks.UberfireDocks; import org.uberfire.ext.editor.commons.client.file.CommandWithFileNameAndCommitMessage; import org.uberfire.ext.editor.commons.client.file.FileNameAndCommitMessage; import org.uberfire.ext.editor.commons.client.file.popups.CopyPopUpPresenter; import org.uberfire.ext.editor.commons.client.file.popups.DeletePopUpPresenter; import org.uberfire.ext.editor.commons.client.file.popups.RenamePopUpPresenter; import org.uberfire.ext.editor.commons.client.validation.Validator; import org.uberfire.ext.editor.commons.client.validation.ValidatorCallback; import org.uberfire.ext.widgets.common.client.callbacks.HasBusyIndicatorDefaultErrorCallback; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.workbench.events.NotificationEvent; import org.uberfire.workbench.events.ResourceAddedEvent; import org.uberfire.workbench.events.ResourceCopiedEvent; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdatedEvent; public abstract class BaseViewPresenter implements BranchChangeHandler { @Inject protected User identity; @Inject protected PlaceManager placeManager; @Inject protected Caller<ExplorerService> explorerService; @Inject protected Caller<BuildService> buildService; @Inject protected Caller<VFSService> vfsService; @Inject protected Caller<ValidationService> validationService; @Inject protected Event<BuildResults> buildResultsEvent; @Inject protected Event<ProjectContextChangeEvent> contextChangedEvent; @Inject private Event<NotificationEvent> notification; @Inject private ActiveContextItems activeContextItems; @Inject private ActiveContextManager activeContextManager; @Inject protected ActiveContextOptions activeOptions; @Inject private ProjectContext context; @Inject protected DeletePopUpPresenter deletePopUpPresenter; @Inject protected RenamePopUpPresenter renamePopUpPresenter; @Inject protected CopyPopUpPresenter copyPopUpPresenter; @Inject protected ValidationPopup validationPopup; private boolean isOnLoading = false; private BaseViewImpl baseView; protected Set<String> activeContentTags = new TreeSet<String>(); protected String currentTag = null; public BaseViewPresenter( BaseViewImpl baseView ) { this.baseView = baseView; } @PostConstruct public void init() { activeContextManager.init( baseView, getContentCallback() ); baseView.init( this ); } public void onActiveOptionsChange( final @Observes ActiveOptionsChangedEvent changedEvent ) { final boolean isVisible = isViewVisible(); setVisible( isVisible ); if ( isVisible ) { initialiseViewForActiveContext( context ); } } protected abstract boolean isViewVisible(); public void update() { baseView.showHiddenFiles( activeOptions.areHiddenFilesVisible() ); baseView.setNavType( getNavType() ); if ( activeOptions.isHeaderNavigationHidden() ) { baseView.hideHeaderNavigator(); } else { baseView.showHeaderNavigator(); } if ( activeOptions.canShowTag() ) { baseView.showTagFilter(); activeContextManager.refresh(); } else { baseView.hideTagFilter(); if ( activeContextItems.getActiveContent() != null ) { baseView.setItems( activeContextItems.getActiveContent() ); } } } private Explorer.NavType getNavType() { if ( activeOptions.isTreeNavigatorVisible() ) { return Explorer.NavType.TREE; } else { return Explorer.NavType.BREADCRUMB; } } public void refresh() { baseView.showBusyIndicator( CommonConstants.INSTANCE.Loading() ); activeContextManager.refresh(); } public void loadContent( final FolderItem item ) { explorerService.call( new RemoteCallback<FolderListing>() { @Override public void callback( FolderListing fl ) { baseView.getExplorer() .loadContent( fl ); } } ) .getFolderListing( activeContextItems.getActiveOrganizationalUnit(), activeContextItems.getActiveRepository(), activeContextItems.getActiveBranch(), activeContextItems.getActiveProject(), item, activeOptions.getOptions() ); } public FolderListing getActiveContent() { return activeContextItems.getActiveContent(); } public void deleteItem( final FolderItem folderItem ) { final Path path = getFolderItemPath( folderItem ); validationService.call( messages -> { if ( ( (List<ValidationMessage>) messages ).isEmpty() ) { showDeletePopup( folderItem ); } else { validationPopup.showDeleteValidationMessages( () -> showDeletePopup( folderItem ), () -> {}, (List<ValidationMessage>) messages ); } } ).validateForDelete( path ); } private void showDeletePopup( final FolderItem folderItem ) { deletePopUpPresenter.show( new ParameterizedCommand<String>() { @Override public void execute( final String comment ) { baseView.showBusyIndicator( CommonConstants.INSTANCE.Deleting() ); explorerService.call( new RemoteCallback<Object>() { @Override public void callback( Object o ) { notification.fire( new NotificationEvent( CommonConstants.INSTANCE.ItemDeletedSuccessfully() ) ); activeContextManager.refresh(); } }, new HasBusyIndicatorDefaultErrorCallback( baseView ) ) .deleteItem( folderItem, comment ); } } ); } public void renameItem( final FolderItem folderItem ) { final Path path = getFolderItemPath( folderItem ); renamePopUpPresenter.show( path, new Validator() { @Override public void validate( final String value, final ValidatorCallback callback ) { validationService.call( new RemoteCallback<Object>() { @Override public void callback( Object response ) { if ( Boolean.TRUE.equals( response ) ) { callback.onSuccess(); } else { callback.onFailure(); } } } ) .isFileNameValid( path, value ); } }, new CommandWithFileNameAndCommitMessage() { @Override public void execute( final FileNameAndCommitMessage details ) { baseView.showBusyIndicator( CommonConstants.INSTANCE.Renaming() ); explorerService.call( getRenameSuccessCallback( getRenameView() ), getRenameErrorCallback( getRenameView() ) ) .renameItem( folderItem, details.getNewFileName(), details.getCommitMessage() ); } } ); } protected RemoteCallback<Void> getRenameSuccessCallback( final RenamePopUpPresenter.View renamePopupView ) { return new RemoteCallback<Void>() { @Override public void callback( final Void o ) { renamePopupView.hide(); notification.fire( new NotificationEvent( CommonConstants.INSTANCE.ItemRenamedSuccessfully() ) ); baseView.hideBusyIndicator(); refresh(); } }; } protected HasBusyIndicatorDefaultErrorCallback getRenameErrorCallback( final RenamePopUpPresenter.View renamePopupView ) { return new HasBusyIndicatorDefaultErrorCallback( baseView ) { @Override public boolean error( final Message message, final Throwable throwable ) { renamePopupView.hide(); return super.error( message, throwable ); } }; } public void copyItem( final FolderItem folderItem ) { final Path path = getFolderItemPath( folderItem ); validationService.call( messages -> { if ( ( (List<ValidationMessage>) messages).isEmpty() ) { showCopyPopup( folderItem, path ); } else { validationPopup.showCopyValidationMessages( () -> showCopyPopup( folderItem, path ), () -> {}, ( List<ValidationMessage>) messages ); } } ).validateForCopy( path ); } private void showCopyPopup( final FolderItem folderItem, final Path path ) { copyPopUpPresenter.show( path, new Validator() { @Override public void validate( final String value, final ValidatorCallback callback ) { validationService.call( new RemoteCallback<Object>() { @Override public void callback( Object response ) { if ( Boolean.TRUE.equals( response ) ) { callback.onSuccess(); } else { callback.onFailure(); } } } ) .isFileNameValid( path, value ); } }, new CommandWithFileNameAndCommitMessage() { @Override public void execute( final FileNameAndCommitMessage details ) { baseView.showBusyIndicator( CommonConstants.INSTANCE.Copying() ); explorerService.call( getCopySuccessCallback( getCopyView() ), getCopyErrorCallback( getCopyView() ) ) .copyItem( folderItem, details.getNewFileName(), getCopyView().getTargetPath(), details.getCommitMessage() ); } } ); } protected RemoteCallback<Void> getCopySuccessCallback( final CopyPopUpPresenter.View copyPopupView ) { return new RemoteCallback<Void>() { @Override public void callback( final Void o ) { copyPopupView.hide(); notification.fire( new NotificationEvent( CommonConstants.INSTANCE.ItemCopiedSuccessfully() ) ); baseView.hideBusyIndicator(); refresh(); } }; } protected HasBusyIndicatorDefaultErrorCallback getCopyErrorCallback( final CopyPopUpPresenter.View copyPopupView ) { return new HasBusyIndicatorDefaultErrorCallback( baseView ) { @Override public boolean error( final Message message, final Throwable throwable ) { copyPopupView.hide(); return super.error( message, throwable ); } }; } public void uploadArchivedFolder( final FolderItem folderItem ) { if ( folderItem.getItem() instanceof Path ) { final Path path = (Path) folderItem.getItem(); Window.open( URLHelper.getDownloadUrl( path ), "downloading", "resizable=no,scrollbars=yes,status=no" ); } } private Path getFolderItemPath( final FolderItem folderItem ) { if ( folderItem.getItem() instanceof Package ) { final Package pkg = ( (Package) folderItem.getItem() ); return pkg.getPackageMainSrcPath(); } else if ( folderItem.getItem() instanceof Path ) { return (Path) folderItem.getItem(); } return null; } private void loadContent( final FolderListing content ) { if ( !activeContextItems.getActiveContent() .equals( content ) ) { setActiveContent( content ); baseView.getExplorer() .loadContent( content ); } } protected void setActiveContent( FolderListing activeContent ) { activeContextItems.setActiveContent( activeContent ); resetTags( false ); } protected void resetTags( boolean maintainSelection ) { if ( !activeOptions.canShowTag() ) { return; } if ( !maintainSelection ) { currentTag = null; } activeContentTags.clear(); for ( FolderItem item : activeContextItems.getActiveContent() .getContent() ) { if ( item.getTags() != null ) { activeContentTags.addAll( item.getTags() ); } } } public String getCurrentTag() { return currentTag; } public Set<String> getActiveContentTags() { return activeContentTags; } private RemoteCallback<ProjectExplorerContent> getContentCallback() { return new RemoteCallback<ProjectExplorerContent>() { @Override public void callback( final ProjectExplorerContent content ) { doContentCallback( content ); } }; } //Process callback in separate method to better support testing void doContentCallback( final ProjectExplorerContent content ) { boolean buildSelectedProject = false; boolean signalChange = activeContextItems.setupActiveOrganizationalUnit( content ); if ( activeContextItems.setupActiveRepository( content ) ) { signalChange = true; } if ( activeContextItems.setupActiveBranch( content ) ) { signalChange = true; } if ( activeContextItems.setupActiveProject( content ) ) { signalChange = true; buildSelectedProject = true; } boolean folderChange = activeContextItems.setupActiveFolderAndPackage( content ); if ( signalChange || folderChange ) { activeContextItems.fireContextChangeEvent(); } if ( buildSelectedProject ) { buildProject( activeContextItems.getActiveProject() ); } setActiveContent( content.getFolderListing() ); baseView.getExplorer() .clear(); activeContextItems.setRepositories( content.getRepositories() ); baseView.setContent( activeContextItems.getActiveProject(), activeContextItems.getActiveContent(), content.getSiblings() ); if ( activeContextItems.getActiveFolderItem() == null ) { activeContextItems.setupActiveFolderAndPackage( content ); } baseView.hideBusyIndicator(); } private void buildProject( final Project project ) { //Don't build automatically if disabled if ( ApplicationPreferences.getBooleanPref( ExplorerService.BUILD_PROJECT_PROPERTY_NAME ) ) { return; } if ( project == null ) { return; } buildService.call( new RemoteCallback<BuildResults>() { @Override public void callback( final BuildResults results ) { buildResultsEvent.fire( results ); } } ) .build( project ); } @Override public void onBranchSelected( final String branch ) { if ( Utils.hasBranchChanged( branch, activeContextItems.getActiveBranch() ) ) { baseView.getExplorer() .clear(); activeContextManager.initActiveContext( activeContextItems.getActiveOrganizationalUnit(), activeContextItems.getActiveRepository(), branch ); } } public void onProjectSelected( final Project project ) { if ( Utils.hasProjectChanged( project, activeContextItems.getActiveProject() ) ) { baseView.getExplorer() .clear(); activeContextManager.initActiveContext( activeContextItems.getActiveOrganizationalUnit(), activeContextItems.getActiveRepository(), activeContextItems.getActiveBranch(), project ); } } public void onActiveFolderItemSelected( final FolderItem item ) { if ( !isOnLoading && Utils.hasFolderItemChanged( item, activeContextItems.getActiveFolderItem() ) ) { activeContextItems.setActiveFolderItem( item ); activeContextItems.fireContextChangeEvent(); //Show busy popup. Once Items are loaded it is closed baseView.showBusyIndicator( CommonConstants.INSTANCE.Loading() ); explorerService.call( new RemoteCallback<FolderListing>() { @Override public void callback( final FolderListing folderListing ) { isOnLoading = true; loadContent( folderListing ); baseView.setItems( folderListing ); baseView.hideBusyIndicator(); isOnLoading = false; } }, new HasBusyIndicatorDefaultErrorCallback( baseView ) ) .getFolderListing( activeContextItems.getActiveOrganizationalUnit(), activeContextItems.getActiveRepository(), activeContextItems.getActiveBranch(), activeContextItems.getActiveProject(), item, activeOptions.getOptions() ); } } public void onItemSelected( final FolderItem folderItem ) { final Object _item = folderItem.getItem(); if ( _item == null ) { return; } if ( folderItem.getType() .equals( FolderItemType.FILE ) && _item instanceof Path ) { placeManager.goTo( (Path) _item ); } else { onActiveFolderItemSelected( folderItem ); } } public void setVisible( final boolean visible ) { baseView.setVisible( visible ); } public void onTagFilterChanged( @Observes TagChangedEvent event ) { if ( !baseView.isVisible() ) { return; } if ( !activeOptions.canShowTag() ) { return; } filterByTag( event.getTag() ); } protected void filterByTag( String tag ) { currentTag = tag; List<FolderItem> filteredItems = new ArrayList<FolderItem>(); for ( FolderItem item : activeContextItems.getActiveContent() .getContent() ) { if ( tag == null || item.getTags() .contains( tag ) || item.getType() .equals( FolderItemType.FOLDER ) ) { filteredItems.add( item ); } } FolderListing filteredContent = new FolderListing( activeContextItems.getActiveContent() .getItem(), filteredItems, activeContextItems.getActiveContent() .getSegments() ); baseView.renderItems( filteredContent ); } // Refresh when a Resource has been updated, if it exists in the active package public void onResourceUpdated( @Observes final ResourceUpdatedEvent event ) { refresh( event.getPath() ); } // Refresh when a Resource has been added, if it exists in the active package public void onResourceAdded( @Observes final ResourceAddedEvent event ) { refresh( event.getPath() ); } // Refresh when a Resource has been deleted, if it exists in the active package public void onResourceDeleted( @Observes final ResourceDeletedEvent event ) { refresh( event.getPath() ); } // Refresh when a Resource has been copied, if it exists in the active package public void onResourceCopied( @Observes final ResourceCopiedEvent event ) { refresh( event.getDestinationPath() ); } // Refresh when a lock status changes has occurred, if it affects the active package public void onLockStatusChange( @Observes final LockInfo lockInfo ) { refresh( lockInfo.getFile(), true ); } private void refresh( final Path resource ) { refresh( resource, false ); } private void refresh( final Path resource, boolean force ) { if ( !baseView.isVisible() ) { return; } if ( resource == null || activeContextItems.getActiveProject() == null ) { return; } if ( !force && !Utils.isInFolderItem( activeContextItems.getActiveFolderItem(), resource ) ) { return; } explorerService.call( new RemoteCallback<FolderListing>() { @Override public void callback( final FolderListing folderListing ) { activeContextItems.setActiveContent( folderListing ); if ( activeOptions.canShowTag() ) { resetTags( true ); filterByTag( currentTag ); } else { baseView.setItems( folderListing ); } } } ) .getFolderListing( activeContextItems.getActiveOrganizationalUnit(), activeContextItems.getActiveRepository(), activeContextItems.getActiveBranch(), activeContextItems.getActiveProject(), activeContextItems.getActiveFolderItem(), activeOptions.getOptions() ); } public void initialiseViewForActiveContext( ProjectContext context ) { activeContextManager.initActiveContext( context ); } public void initialiseViewForActiveContext( String initPath ) { activeContextManager.initActiveContext( initPath ); } // Refresh when a Resource has been renamed, if it exists in the active package public void onResourceRenamed( @Observes final ResourceRenamedEvent event ) { if ( !baseView.isVisible() ) { return; } final Path sourcePath = event.getPath(); final Path destinationPath = event.getDestinationPath(); boolean refresh = false; if ( Utils.isInFolderItem( activeContextItems.getActiveFolderItem(), sourcePath ) ) { refresh = true; } else if ( Utils.isInFolderItem( activeContextItems.getActiveFolderItem(), destinationPath ) ) { refresh = true; } if ( refresh ) { explorerService.call( new RemoteCallback<FolderListing>() { @Override public void callback( final FolderListing folderListing ) { baseView.setItems( folderListing ); } } ) .getFolderListing( activeContextItems.getActiveOrganizationalUnit(), activeContextItems.getActiveRepository(), activeContextItems.getActiveBranch(), activeContextItems.getActiveProject(), activeContextItems.getActiveFolderItem(), activeOptions.getOptions() ); } } RenamePopUpPresenter.View getRenameView() { return renamePopUpPresenter.getView(); } CopyPopUpPresenter.View getCopyView() { return copyPopUpPresenter.getView(); } @Inject private UberfireDocks uberfireDocks; }