/* * 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.widgets.maindomain; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.Widget; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.kie.workbench.common.screens.datamodeller.client.DataModelerContext; import org.kie.workbench.common.screens.datamodeller.client.command.DataModelCommand; import org.kie.workbench.common.screens.datamodeller.client.command.DataModelCommandBuilder; import org.kie.workbench.common.screens.datamodeller.client.handlers.DomainHandlerRegistry; import org.kie.workbench.common.screens.datamodeller.client.resources.i18n.Constants; import org.kie.workbench.common.screens.datamodeller.client.util.AnnotationValueHandler; import org.kie.workbench.common.screens.datamodeller.client.util.DataModelerUtils; import org.kie.workbench.common.screens.datamodeller.client.util.UIUtil; import org.kie.workbench.common.screens.datamodeller.client.validation.ValidatorService; import org.kie.workbench.common.screens.datamodeller.client.widgets.common.domain.ObjectEditor; import org.kie.workbench.common.screens.datamodeller.events.DataModelerEvent; import org.kie.workbench.common.screens.datamodeller.model.maindomain.MainDomainAnnotations; import org.kie.workbench.common.screens.datamodeller.service.DataModelerService; import org.kie.workbench.common.services.datamodeller.core.Annotation; import org.kie.workbench.common.services.datamodeller.core.DataModel; import org.kie.workbench.common.services.datamodeller.core.DataObject; import org.uberfire.backend.vfs.Path; import org.uberfire.ext.editor.commons.client.validation.ValidatorCallback; @Dependent public class MainDataObjectEditor extends ObjectEditor implements MainDataObjectEditorView.Presenter { private MainDataObjectEditorView view; private ValidatorService validatorService; private Caller<DataModelerService> modelerService; @Inject public MainDataObjectEditor( MainDataObjectEditorView view, DomainHandlerRegistry handlerRegistry, Event<DataModelerEvent> dataModelerEvent, DataModelCommandBuilder commandBuilder, ValidatorService validatorService, Caller<DataModelerService> modelerService ) { super( handlerRegistry, dataModelerEvent, commandBuilder ); this.view = view; this.validatorService = validatorService; this.modelerService = modelerService; view.init( this ); } @PostConstruct protected void init() { setReadonly( true ); } @Override public Widget asWidget() { return view.asWidget(); } @Override public String getName() { return "MAIN_OBJECT_EDITOR"; } @Override public String getDomainName() { return MainDomainEditor.MAIN_DOMAIN; } public void onContextChange( DataModelerContext context ) { this.context = context; view.initPackageSelector( context ); super.onContextChange( context ); } private DataModel getDataModel() { return getContext() != null ? getContext().getDataModel() : null; } public void refreshTypeList( boolean keepSelection ) { initSuperClassList( keepSelection ); } public void setReadonly( boolean readonly ) { super.setReadonly( readonly ); view.setReadonly( readonly ); } @Override public void onNameChange() { if ( getDataObject() != null ) { view.setNameOnError( false ); final String packageName = getDataObject().getPackageName(); final String oldValue = getDataObject().getName(); final String newValue = view.getName(); final String originalClassName = getContext() != null ? getContext().getEditorModelContent().getOriginalClassName() : null; final Path currentPath = getContext() != null && getContext().getEditorModelContent() != null ? getContext().getEditorModelContent().getPath() : null; if ( originalClassName != null ) { modelerService.call( new RemoteCallback<List<Path>>() { @Override public void callback( List<Path> paths ) { if ( paths != null && paths.size() > 0 ) { //If usages for this field were detected in project assets //show the confirmation message to the user. view.showUsagesPopupForRenaming( Constants.INSTANCE.modelEditor_confirm_renaming_of_used_class( originalClassName ), paths, new org.uberfire.mvp.Command() { @Override public void execute() { doClassNameChange( packageName, oldValue, newValue ); } }, new org.uberfire.mvp.Command() { @Override public void execute() { //do nothing. view.setName( oldValue ); } } ); } else { //no usages, just proceed with the class name change. doClassNameChange( packageName, oldValue, newValue ); } } } ).findClassUsages( currentPath, originalClassName ); } else { doClassNameChange( packageName, oldValue, newValue ); } } } @Override public void onLabelChange() { if ( getDataObject() != null ) { String value = DataModelerUtils.nullTrim( view.getLabel() ); DataModelCommand command = commandBuilder.buildDataObjectAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), MainDomainAnnotations.LABEL_ANNOTATION, "value", value, true ); command.execute(); } } @Override public void onDescriptionChange() { if ( getDataObject() != null ) { String value = DataModelerUtils.nullTrim( view.getDescription() ); DataModelCommand command = commandBuilder.buildDataObjectAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), MainDomainAnnotations.DESCRIPTION_ANNOTATION, "value", value, true ); command.execute(); } } @Override public void onSuperClassChange() { if ( getDataObject() != null ) { view.setSuperClassOnError( false ); final String newSuperClass = view.getSuperClass(); final String oldSuperClass = getDataObject().getSuperClassName(); // No change needed if ( ( ( "".equals( newSuperClass ) || UIUtil.NOT_SELECTED.equals( newSuperClass ) ) && oldSuperClass == null ) || newSuperClass.equals( oldSuperClass ) ) { return; } if ( newSuperClass != null && !"".equals( newSuperClass ) && !UIUtil.NOT_SELECTED.equals( newSuperClass ) ) { validatorService.canExtend( getContext(), getDataObject().getClassName(), newSuperClass, new ValidatorCallback() { @Override public void onFailure() { view.showErrorPopup( Constants.INSTANCE.validation_error_cyclic_extension( getDataObject().getClassName(), newSuperClass ), null, new Command() { @Override public void execute() { view.setSuperClassOnError( true ); view.setSuperClassOnFocus(); } } ); } @Override public void onSuccess() { commandBuilder.buildDataObjectSuperClassChangeCommand( getContext(), getName(), getDataObject(), newSuperClass ).execute(); getDataObject().setSuperClassName( newSuperClass ); } } ); } else { commandBuilder.buildDataObjectSuperClassChangeCommand( getContext(), getName(), getDataObject(), null ).execute(); } } } @Override public void onPackageAdded() { if ( getDataObject() != null ) { doPackageChange( view.getNewPackageName() ); } } @Override public void onPackageChange() { if ( getDataObject() != null ) { doPackageChange( view.getPackageName() ); } } public void doPackageChange( String packageName ) { if ( getDataObject() != null ) { view.setPackageNameOnError( false ); final String originalClassName = getContext() != null ? getContext().getEditorModelContent().getOriginalClassName() : null; final String newPackageName = packageName != null && !"".equals( packageName ) && !UIUtil.NOT_SELECTED.equals( packageName ) ? packageName : null; final String oldPackageName = getDataObject().getPackageName(); final Path currentPath = getContext() != null && getContext().getEditorModelContent() != null ? getContext().getEditorModelContent().getPath() : null; if ( ( oldPackageName != null && !oldPackageName.equals( newPackageName ) ) || ( oldPackageName == null && newPackageName != null ) ) { //the user is trying to change the package name modelerService.call( new RemoteCallback<List<Path>>() { @Override public void callback( List<Path> paths ) { if ( paths != null && paths.size() > 0 ) { //If usages for this class were detected in project assets //show the confirmation message to the user. view.showUsagesPopupForChanging( Constants.INSTANCE.modelEditor_confirm_package_change_of_used_class( originalClassName ), paths, new org.uberfire.mvp.Command() { @Override public void execute() { doPackageChange( oldPackageName, newPackageName ); } }, new org.uberfire.mvp.Command() { @Override public void execute() { //do nothing. view.setPackageName( oldPackageName ); } } ); } else { //no usages, just proceed with the package change. doPackageChange( oldPackageName, newPackageName ); } } } ).findClassUsages( currentPath, originalClassName ); } else { doPackageChange( oldPackageName, newPackageName ); } } } @Override protected void loadDataObject( DataObject dataObject ) { clear(); setReadonly( true ); if ( dataObject != null ) { this.dataObject = dataObject; view.setName( dataObject.getName() ); Annotation annotation = dataObject.getAnnotation( MainDomainAnnotations.LABEL_ANNOTATION ); if ( annotation != null ) { view.setLabel( AnnotationValueHandler.getStringValue( annotation, MainDomainAnnotations.VALUE_PARAM ) ); } annotation = dataObject.getAnnotation( MainDomainAnnotations.DESCRIPTION_ANNOTATION ); if ( annotation != null ) { view.setDescription( AnnotationValueHandler.getStringValue( annotation, MainDomainAnnotations.VALUE_PARAM ) ); } view.setPackageName( dataObject.getPackageName() ); initSuperClassList( false ); setReadonly( getContext() == null || getContext().isReadonly() ); } } private void initSuperClassList( boolean keepSelection ) { String currentValue = keepSelection ? view.getSuperClass() : ( dataObject != null ? dataObject.getSuperClassName() : null ); view.initSuperClassList( DataModelerUtils.buildSuperclassOptions( getDataModel(), dataObject ), currentValue ); } private void doClassNameChange( final String packageName, final String oldValue, final String newValue ) { final Command afterCloseCommand = new Command() { @Override public void execute() { view.setNameOnError( true ); view.setAllNameNameText(); } }; // In case an invalid name (entered before), was corrected to the original value, don't do anything but reset the label style if ( oldValue.equals( newValue ) ) { view.setNameOnError( false ); return; } // Otherwise validate validatorService.isValidIdentifier( newValue, new ValidatorCallback() { @Override public void onFailure() { view.showErrorPopup( Constants.INSTANCE.validation_error_invalid_object_identifier( newValue ), null, afterCloseCommand ); } @Override public void onSuccess() { validatorService.isUniqueEntityName( packageName, newValue, getDataModel(), new ValidatorCallback() { @Override public void onFailure() { view.showErrorPopup( Constants.INSTANCE.validation_error_object_already_exists( newValue, packageName ), null, afterCloseCommand ); } @Override public void onSuccess() { view.setNameOnError( false ); commandBuilder.buildDataObjectNameChangeCommand( getContext(), getName(), getDataObject(), newValue ).execute(); } } ); } } ); } private void doPackageChange( String oldPackageName, String newPackageName ) { commandBuilder.buildDataObjectPackageChangeCommand( getContext(), getName(), getDataObject(), newPackageName ).execute(); } public void clear() { view.setNameOnError( false ); view.setName( null ); view.setLabel( null ); view.setDescription( null ); view.setPackageNameOnError( false ); view.clearPackageList(); view.clearSuperClassList(); view.setSuperClassOnError( false ); } }