/* * 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.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; 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.validation.ValidatorService; import org.kie.workbench.common.screens.datamodeller.client.widgets.common.domain.FieldEditor; import org.kie.workbench.common.screens.datamodeller.events.ChangeType; import org.kie.workbench.common.screens.datamodeller.events.DataModelerEvent; import org.kie.workbench.common.screens.datamodeller.events.DataObjectChangeEvent; 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.kie.workbench.common.services.datamodeller.core.ObjectProperty; import org.uberfire.backend.vfs.Path; import org.uberfire.commons.data.Pair; import org.uberfire.ext.editor.commons.client.validation.ValidatorCallback; import org.uberfire.ext.editor.commons.client.validation.ValidatorWithReasonCallback; import org.uberfire.mvp.Command; @Dependent public class MainDataObjectFieldEditor extends FieldEditor implements MainDataObjectFieldEditorView.Presenter { private MainDataObjectFieldEditorView view; private ValidatorService validatorService; private Caller<DataModelerService> modelerService; @Inject public MainDataObjectFieldEditor( MainDataObjectFieldEditorView 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 ); } public void onContextChange( DataModelerContext context ) { this.context = context; initTypeList(); view.setMultipleTypeEnabled( false ); super.onContextChange( context ); } @Override public String getName() { return "MAIN_FIELD_EDITOR"; } @Override public String getDomainName() { return MainDomainEditor.MAIN_DOMAIN; } private DataModel getDataModel() { return getContext() != null ? getContext().getDataModel() : null; } public void setReadonly( boolean readonly ) { super.setReadonly( readonly ); view.setReadonly( readonly ); } @Override public Widget asWidget() { return view.asWidget(); } @Override public void onNameChange() { if ( getObjectField() == null ) { return; } view.setNameOnError( false ); final String oldValue = getObjectField().getName(); final String newValue = DataModelerUtils.unCapitalize( 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_field( oldValue ), paths, new Command() { @Override public void execute() { doFieldNameChange( oldValue, newValue ); } }, new Command() { @Override public void execute() { //do nothing. view.setName( oldValue ); } } ); } else { //no usages, just proceed with the deletion. doFieldNameChange( oldValue, newValue ); } } } ).findFieldUsages( currentPath, originalClassName, oldValue ); } else { doFieldNameChange( oldValue, newValue ); } } @Override public void onLabelChange() { if ( getObjectField() != null ) { String value = DataModelerUtils.nullTrim( view.getLabel() ); DataModelCommand command = commandBuilder.buildFieldAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), getObjectField(), MainDomainAnnotations.LABEL_ANNOTATION, MainDomainAnnotations.VALUE_PARAM, value, true ); command.execute(); } } @Override public void onDescriptionChange() { if ( getObjectField() != null ) { String value = DataModelerUtils.nullTrim( view.getDescription() ); DataModelCommand command = commandBuilder.buildFieldAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), getObjectField(), MainDomainAnnotations.DESCRIPTION_ANNOTATION, MainDomainAnnotations.VALUE_PARAM, value, true ); command.execute(); } } @Override public void onTypeChange() { doTypeChange( view.getType(), view.getMultipleType() ); } @Override public void onTypeMultipleChange() { doTypeChange( view.getType(), view.getMultipleType() ); } private void onDataObjectChange( @Observes DataObjectChangeEvent event ) { if ( event.isFromContext( context != null ? context.getContextId() : null ) ) { if ( "name".equals( event.getValueName() ) || "packageName".equals( event.getValueName() ) || "label".equals( event.getValueName() ) ) { initTypeList(); } } } @Override protected void loadDataObjectField( DataObject dataObject, ObjectProperty objectField ) { clear(); setReadonly( true ); if ( dataObject != null && objectField != null ) { this.dataObject = dataObject; this.objectField = objectField; initTypeList(); view.setName( getObjectField().getName() ); Annotation annotation = objectField.getAnnotation( MainDomainAnnotations.LABEL_ANNOTATION ); if ( annotation != null ) { view.setLabel( AnnotationValueHandler.getStringValue( annotation, MainDomainAnnotations.VALUE_PARAM ) ); } annotation = objectField.getAnnotation( MainDomainAnnotations.DESCRIPTION_ANNOTATION ); if ( annotation != null ) { view.setDescription( AnnotationValueHandler.getStringValue( annotation, MainDomainAnnotations.VALUE_PARAM ) ); } setReadonly( getContext() == null || getContext().isReadonly() ); } else { initTypeList(); } } private void doFieldNameChange( final String oldValue, final String newValue ) { final Command afterCloseCommand = new Command() { @Override public void execute() { view.setNameOnError( true ); view.selectAllNameText(); } }; // In case an invalid name (entered before), was corrected to the original value, don't do anything but reset the label style if ( oldValue.equalsIgnoreCase( view.getName() ) ) { view.setName( oldValue ); view.setNameOnError( false ); return; } validatorService.isValidIdentifier( newValue, new ValidatorCallback() { @Override public void onFailure() { view.showErrorPopup( Constants.INSTANCE.validation_error_invalid_object_attribute_identifier( newValue ), null, afterCloseCommand ); } @Override public void onSuccess() { validatorService.isUniqueAttributeName( newValue, getDataObject(), new ValidatorWithReasonCallback() { @Override public void onFailure() { showFailure( ValidatorService.MANAGED_PROPERTY_EXISTS ); } @Override public void onFailure( String reason ) { showFailure( reason ); } private void showFailure( String reason ) { if ( ValidatorService.UN_MANAGED_PROPERTY_EXISTS.equals( reason ) ) { ObjectProperty unmanagedProperty = getDataObject().getUnManagedProperty( newValue ); view.showErrorPopup( Constants.INSTANCE.validation_error_object_un_managed_attribute_already_exists( unmanagedProperty.getName(), unmanagedProperty.getClassName() ) ); } else { view.showErrorPopup( Constants.INSTANCE.validation_error_object_attribute_already_exists( newValue ) ); } } @Override public void onSuccess() { view.setNameOnError( false ); objectField.setName( newValue ); notifyChange( createFieldChangeEvent( ChangeType.FIELD_NAME_CHANGE ) .withOldValue( oldValue ) .withNewValue( newValue ) ); } } ); } } ); } private void doTypeChange( String newType, boolean isMultiple ) { if ( getObjectField() != null ) { boolean multiple = isMultiple; if ( getContext().getHelper().isPrimitiveType( newType ) ) { view.setMultipleTypeEnabled( false ); view.setMultipleType( false ); multiple = false; } else { view.setMultipleTypeEnabled( true ); } DataModelCommand command = commandBuilder.buildChangeTypeCommand( getContext(), getName(), getDataObject(), getObjectField(), newType, multiple ); command.execute(); executePostCommandProcessing( command ); } } private void initTypeList() { String currentFieldType = null; boolean currentFieldTypeMultiple = false; view.setMultipleTypeEnabled( true ); view.setMultipleType( false ); if ( getDataModel() != null ) { if ( getDataObject() != null && getObjectField() != null ) { currentFieldType = getObjectField().getClassName(); currentFieldTypeMultiple = getObjectField().isMultiple(); if ( getContext().getHelper().isPrimitiveType( currentFieldType ) ) { view.setMultipleTypeEnabled( false ); view.setMultipleType( false ); } else { view.setMultipleType( currentFieldTypeMultiple ); } } List<Pair<String, String>> typeList = DataModelerUtils.buildFieldTypeOptions( getContext().getHelper().getOrderedBaseTypes().values(), getDataModel().getDataObjects(), getDataModel().getJavaEnums(), getDataModel().getExternalClasses(), getDataModel().getDependencyJavaEnums(), currentFieldType, false ); view.initTypeList( typeList, currentFieldType, false ); } else { view.initTypeList( new ArrayList<Pair<String, String>>(), null, false ); } } public void refreshTypeList( boolean keepSelection ) { String selectedValue = view.getType(); initTypeList(); if ( keepSelection && selectedValue != null ) { view.setType( selectedValue ); } } public void clear() { view.setNameOnError( false ); view.setName( null ); view.setLabel( null ); view.setDescription( null ); view.setType( "" ); } }