/* * Copyright 2015 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.datamodeller.client; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.guvnor.common.services.shared.validation.model.ValidationMessage; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.kie.workbench.common.screens.datamodeller.client.pdescriptor.ClassRow; import org.kie.workbench.common.screens.datamodeller.client.pdescriptor.ClassRowImpl; import org.kie.workbench.common.screens.datamodeller.client.widgets.datasourceselector.DataSourceInfo; import org.kie.workbench.common.screens.datamodeller.client.widgets.datasourceselector.DataSourceSelector; import org.kie.workbench.common.screens.datamodeller.client.pdescriptor.PropertyRow; import org.kie.workbench.common.screens.datamodeller.client.resources.i18n.Constants; import org.kie.workbench.common.screens.datamodeller.client.type.PersistenceDescriptorType; import org.kie.workbench.common.screens.datamodeller.model.persistence.PersistenceDescriptorEditorContent; import org.kie.workbench.common.screens.datamodeller.model.persistence.PersistenceDescriptorModel; import org.kie.workbench.common.screens.datamodeller.model.persistence.PersistenceUnitModel; import org.kie.workbench.common.screens.datamodeller.model.persistence.Property; import org.kie.workbench.common.screens.datamodeller.model.persistence.TransactionType; import org.kie.workbench.common.screens.datamodeller.service.DataModelerService; import org.kie.workbench.common.screens.datamodeller.service.PersistenceDescriptorEditorService; import org.kie.workbench.common.screens.datamodeller.service.PersistenceDescriptorService; import org.kie.workbench.common.services.shared.preferences.ApplicationPreferences; import org.kie.workbench.common.widgets.client.popups.validation.ValidationPopup; import org.kie.workbench.common.widgets.client.resources.i18n.CommonConstants; import org.kie.workbench.common.widgets.metadata.client.KieEditor; import org.uberfire.annotations.Customizable; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.client.annotations.WorkbenchEditor; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartTitleDecoration; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.views.pfly.multipage.PageImpl; import org.uberfire.ext.widgets.common.client.callbacks.DefaultErrorCallback; import org.uberfire.ext.widgets.common.client.callbacks.HasBusyIndicatorDefaultErrorCallback; import org.uberfire.lifecycle.OnClose; import org.uberfire.lifecycle.OnFocus; import org.uberfire.lifecycle.OnMayClose; import org.uberfire.lifecycle.OnStartup; import org.uberfire.mvp.Command; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.events.NotificationEvent; import org.uberfire.workbench.model.menu.Menus; @Dependent @WorkbenchEditor( identifier = "PersistenceDescriptorEditor", supportedTypes = { PersistenceDescriptorType.class }, priority = Integer.MAX_VALUE ) public class PersistenceDescriptorEditorPresenter extends KieEditor implements PersistenceDescriptorEditorView.Presenter { private PersistenceDescriptorEditorView view; private PersistenceDescriptorType type; private DataSourceSelector dataSourceSelector; private Caller<PersistenceDescriptorEditorService> editorService; private Caller<PersistenceDescriptorService> descriptorService; private Caller<DataModelerService> dataModelerService; private ValidationPopup validationPopup; private PersistenceDescriptorEditorContent content; private boolean createIfNotExists = false; @Inject public PersistenceDescriptorEditorPresenter( final PersistenceDescriptorEditorView baseView, final PersistenceDescriptorType type, @Customizable final DataSourceSelector dataSourceSelector, final Caller<PersistenceDescriptorEditorService> editorService, final Caller<PersistenceDescriptorService> descriptorService, final Caller<DataModelerService> dataModelerService, final ValidationPopup validationPopup ) { super( baseView ); this.view = baseView; baseView.setPresenter( this ); this.type = type; this.dataSourceSelector = dataSourceSelector; this.editorService = editorService; this.descriptorService = descriptorService; this.dataModelerService = dataModelerService; this.validationPopup = validationPopup; view.showDataSourceSelector( dataSourceIntegrationEnabled( ) ); } @OnStartup public void onStartup( final ObservablePath path, final PlaceRequest place ) { this.createIfNotExists = "true".equals( place.getParameter( "createIfNotExists", null ) ); init( path, place, type ); } @OnFocus public void onFocus() { //for some reason the tables needs to be repainted when the view is restored. view.redraw(); } @WorkbenchPartTitle public String getTitleText() { if ( versionRecordManager.getCurrentPath() != null ) { super.getTitleText(); } else { //TODO check why I'm getting this case and remove after checked return type.getDescription(); } return super.getTitleText(); } @WorkbenchPartTitleDecoration public IsWidget getTitle() { return super.getTitle(); } @WorkbenchPartView public IsWidget getView() { return super.getWidget(); } @WorkbenchMenu public Menus getMenus() { makeMenuBar(); return super.menus; } @Override protected void loadContent() { editorService.call( getLoadModelSuccessCallback(), new HasBusyIndicatorDefaultErrorCallback( view ) ).loadContent( versionRecordManager.getCurrentPath(), createIfNotExists ); } @OnMayClose public boolean onMayClose() { if ( isDirty( getContent().hashCode() ) ) { return view.confirmClose(); } return true; } @OnClose public void OnClose() { super.OnClose(); } private RemoteCallback<PersistenceDescriptorEditorContent> getLoadModelSuccessCallback() { return new RemoteCallback<PersistenceDescriptorEditorContent>() { @Override public void callback( PersistenceDescriptorEditorContent content ) { if ( versionRecordManager.getCurrentPath() == null ) { return; } if ( content.isCreated() ) { versionRecordManager.reloadVersions( content.getPath() ); } resetEditorPages( content.getOverview() ); addSourcePage(); createOriginalHash( content ); setContent( content ); view.setReadOnly( isReadOnly ); updateSource( content.getSource() ); view.hideBusyIndicator(); } }; } private void setContent( PersistenceDescriptorEditorContent content ) { this.content = content; PersistenceDescriptorModel descriptorModel = content != null ? content.getDescriptorModel() : null; PersistenceUnitModel persistenceUnitModel = descriptorModel != null ? descriptorModel.getPersistenceUnit() : null; view.clear(); if ( persistenceUnitModel != null ) { view.setPersistenceUnitName( persistenceUnitModel.getName() ); view.setPersistenceProvider( persistenceUnitModel.getProvider() ); view.setJTADataSource( persistenceUnitModel.getJtaDataSource() ); view.setJTATransactions( false ); view.setResourceLocalTransactions( false ); if ( TransactionType.JTA.equals( persistenceUnitModel.getTransactionType() ) ) { view.setJTATransactions( true ); } else if ( TransactionType.RESOURCE_LOCAL.equals( persistenceUnitModel.getTransactionType() ) ) { view.setResourceLocalTransactions( true ); view.setResourceLocalTransactionsVisible( true ); updateResourceLocalTransactionsAlert(); } view.getPersistenceUnitProperties().setProperties( wrappPropertiesList( persistenceUnitModel.getProperties() ) ); view.getPersistenceUnitClasses().setClasses( wrappClassesList( persistenceUnitModel.getClasses() ) ); } } public PersistenceDescriptorEditorContent getContent() { updateContent(); return content; } protected void addSourcePage() { addPage( new PageImpl( view.getSourceEditor(), CommonConstants.INSTANCE.SourceTabTitle() ) { @Override public void onFocus() { onSourceTabSelected(); } @Override public void onLostFocus() { } } ); } protected void updateSource(String source) { view.setSource( source ); } protected void save() { savePopUpPresenter.show( versionRecordManager.getCurrentPath(), new ParameterizedCommand<String>() { @Override public void execute( final String commitMessage ) { editorService.call( getSaveSuccessCallback( getContent().hashCode() ) ).save( versionRecordManager.getCurrentPath(), getContent(), metadata, commitMessage ); } } ); concurrentUpdateSessionInfo = null; } @Override public void onSourceTabSelected() { PersistenceDescriptorModel persistenceDescriptor = getContent().getDescriptorModel(); if ( persistenceDescriptor != null ) { view.showBusyIndicator( Constants.INSTANCE.persistence_descriptor_editor_loading_source_message() ); descriptorService.call( new RemoteCallback<String>() { @Override public void callback( String source ) { view.hideBusyIndicator(); updateSource( source ); } }, new HasBusyIndicatorDefaultErrorCallback( view ) ).toSource( versionRecordManager.getCurrentPath(), persistenceDescriptor ); } } //Presenter methods @Override public void onPersistenceUnitNameChange() { ensurePersistenceUnit(); getContent().getDescriptorModel().getPersistenceUnit().setName( view.getPersistenceUnitName() ); } @Override public void onPersistenceProviderChange() { ensurePersistenceUnit(); getContent().getDescriptorModel().getPersistenceUnit().setProvider( view.getPersistenceProvider() ); } @Override public void onJTADataSourceChange() { ensurePersistenceUnit(); getContent().getDescriptorModel().getPersistenceUnit().setJtaDataSource( view.getJTADataSource() ); } @Override public void onSelectDataSource() { dataSourceSelector.setGlobalSelection(); dataSourceSelector.show( new ParameterizedCommand<DataSourceInfo>() { @Override public void execute( DataSourceInfo dataSourceInfo ) { ensurePersistenceUnit(); if ( dataSourceInfo.isDeployed() ) { getContent().getDescriptorModel().getPersistenceUnit().setJtaDataSource( dataSourceInfo.getJndi() ); view.setJTADataSource( dataSourceInfo.getJndi() ); } } }, new Command() { @Override public void execute() { //do nothing } } ); } private boolean dataSourceIntegrationEnabled() { return ApplicationPreferences.getBooleanPref( "persistence-descriptor-editor-options.integrate-datasources" ); } @Override public void onJTATransactionsChange() { ensurePersistenceUnit(); getContent().getDescriptorModel().getPersistenceUnit().setTransactionType( view.getJTATransactions() ? TransactionType.JTA : TransactionType.RESOURCE_LOCAL ); updateResourceLocalTransactionsAlert(); } @Override public void onResourceLocalTransactionsChange() { ensurePersistenceUnit(); getContent().getDescriptorModel().getPersistenceUnit().setTransactionType( view.getResourceLocalTransactions() ? TransactionType.RESOURCE_LOCAL : TransactionType.JTA ); updateResourceLocalTransactionsAlert(); } private void updateResourceLocalTransactionsAlert( ) { if ( view.getResourceLocalTransactions() ) { view.setTransactionTypeHelpMessage( Constants.INSTANCE.persistence_descriptor_editor_resource_local_transactions_not_supported_message() ); } else { view.setTransactionTypeHelpMessage( null ); } } @Override public void onLoadClasses() { view.showBusyIndicator( Constants.INSTANCE.persistence_descriptor_editor_loading_classes_message() ); dataModelerService.call( getLoadClassesSuccessCallback(), new HasBusyIndicatorDefaultErrorCallback( view ) ).findPersistableClasses( versionRecordManager.getCurrentPath() ); } @Override public void onLoadClass( final String className ) { view.showBusyIndicator( Constants.INSTANCE.persistence_descriptor_editor_loading_classes_message() ); dataModelerService.call( getLoadClassSuccessCallback( className ), new HasBusyIndicatorDefaultErrorCallback( view ) ).isPersistableClass( className, versionRecordManager.getCurrentPath() ); } @Override protected Command onValidate() { return new Command() { @Override public void execute() { onValidateDescriptor(); } }; } protected void onValidateDescriptor( ) { updateContent( ); descriptorService.call( getValidationSuccessCallback(), new DefaultErrorCallback( ) ).validate( versionRecordManager.getCurrentPath( ), content.getDescriptorModel( ) ); } private RemoteCallback<List<ValidationMessage>> getValidationSuccessCallback() { return new RemoteCallback<List<ValidationMessage>>() { @Override public void callback( List<ValidationMessage> messages ) { if ( messages == null || messages.isEmpty( ) ) { notification.fire( new NotificationEvent( CommonConstants.INSTANCE.ItemValidatedSuccessfully( ), NotificationEvent.NotificationType.SUCCESS ) ); } else { validationPopup.showTranslatedMessages( messages ); } } }; } protected void updateContent() { content.getDescriptorModel().getPersistenceUnit().setProperties( unWrappPropertiesList( view.getPersistenceUnitProperties().getProperties() ) ); content.getDescriptorModel().getPersistenceUnit().setClasses( unWrappClassesList( view.getPersistenceUnitClasses().getClasses() ) ); } private RemoteCallback<List<String>> getLoadClassesSuccessCallback() { return new RemoteCallback<List<String>>() { @Override public void callback( List<String> classes ) { view.hideBusyIndicator(); appendPersistableClasses( classes ); view.getPersistenceUnitClasses().setNewClassHelpMessage( null ); view.getPersistenceUnitClasses().setNewClassName( null ); } }; } private RemoteCallback<Boolean> getLoadClassSuccessCallback( final String className ) { return new RemoteCallback<Boolean>() { @Override public void callback( Boolean persistable ) { view.hideBusyIndicator(); if ( persistable ) { List<String> classes = new ArrayList<String>( ); classes.add( className ); appendPersistableClasses( classes ); view.getPersistenceUnitClasses().setNewClassHelpMessage( null ); view.getPersistenceUnitClasses().setNewClassName( null ); } else { view.getPersistenceUnitClasses().setNewClassHelpMessage( Constants.INSTANCE.persistence_descriptor_editor_peristable_class_not_found( className ) ); } } }; } private void appendPersistableClasses( List<String> classes ) { if ( classes != null && classes.size() > 0 ) { List<String> currentClasses = unWrappClassesList( view.getPersistenceUnitClasses().getClasses() ); for ( String clazz : classes ) { if ( !currentClasses.contains( clazz ) ) { currentClasses.add( clazz ); } } view.getPersistenceUnitClasses().setClasses( wrappClassesList( currentClasses ) ); } } private void ensurePersistenceUnit() { if ( content.getDescriptorModel().getPersistenceUnit() == null ) { content.getDescriptorModel().setPersistenceUnit( new PersistenceUnitModel() ); } } private List<ClassRow> wrappClassesList( List<String> classes ) { List<ClassRow> classRows = new ArrayList<ClassRow>( ); if ( classes == null ) return null; for ( String clazz : classes ) { classRows.add( new ClassRowImpl( clazz ) ); } return classRows; } private List<String> unWrappClassesList( List<ClassRow> classRows ) { List<String> classes = new ArrayList<String>( ); if ( classRows == null ) return null; for ( ClassRow classRow : classRows ) { classes.add( classRow.getClassName() ); } return classes; } private List<PropertyRow> wrappPropertiesList( List<Property> properties ) { List<PropertyRow> wrapperList = new ArrayList<PropertyRow>( ); if ( properties == null ) return null; for ( Property property : properties ) { wrapperList.add( new PropertyWrapperRow( property ) ); } return wrapperList; } private List<Property> unWrappPropertiesList( List<PropertyRow> propertyRows ) { List<Property> properties = new ArrayList<Property>( ); if ( propertyRows == null ) return null; for ( PropertyRow propertyRow : propertyRows ) { properties.add( new Property( propertyRow.getName(), propertyRow.getValue() ) ); } return properties; } public static class PropertyWrapperRow implements PropertyRow { private Property property = new Property( ); public PropertyWrapperRow( Property property ) { if ( property != null ) { this.property = property; } } @Override public String getName() { return property.getName(); } @Override public void setName( String name ) { property.setName( name ); } @Override public String getValue() { return property.getValue(); } @Override public void setValue( String value ) { property.setValue( value ); } } }