/* * 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.droolsdomain; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; 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.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.events.DataObjectFieldChangeEvent; import org.kie.workbench.common.screens.datamodeller.events.DataObjectFieldCreatedEvent; import org.kie.workbench.common.screens.datamodeller.events.DataObjectFieldDeletedEvent; import org.kie.workbench.common.screens.datamodeller.model.droolsdomain.DroolsDomainAnnotations; import org.kie.workbench.common.services.datamodeller.core.Annotation; import org.kie.workbench.common.services.datamodeller.core.DataObject; import org.kie.workbench.common.services.datamodeller.core.ObjectProperty; import org.uberfire.commons.data.Pair; import org.uberfire.ext.editor.commons.client.validation.ValidatorCallback; import org.uberfire.mvp.Command; @Dependent public class DroolsDataObjectEditor extends ObjectEditor implements DroolsDataObjectEditorView.Presenter { private ValidatorService validatorService; private DroolsDataObjectEditorView view; @Inject public DroolsDataObjectEditor( DroolsDataObjectEditorView view, DomainHandlerRegistry handlerRegistry, Event<DataModelerEvent> dataModelerEvent, DataModelCommandBuilder commandBuilder, ValidatorService validatorService ) { super( handlerRegistry, dataModelerEvent, commandBuilder ); this.validatorService = validatorService; this.view = view; view.init( this ); } @PostConstruct protected void init() { List<Pair<String, String>> roleOptions = new ArrayList<Pair<String, String>>( ); roleOptions.add( new Pair<String, String>( "EVENT", "EVENT" ) ); view.initRoleList( roleOptions, true ); List<Pair<String, String>> typeSafeOptions = new ArrayList<Pair<String, String>>( ); typeSafeOptions.add( new Pair<String, String>( "false", "false" ) ); typeSafeOptions.add( new Pair<String, String>( "true", "true" ) ); view.initTypeSafeList( typeSafeOptions, true ); view.initTimeStampFieldList( new ArrayList<Pair<String, String>>(), true ); view.initDurationFieldList( new ArrayList<Pair<String, String>>(), true ); setReadonly( true ); } @Override public Widget asWidget() { return view.asWidget(); } @Override public String getName() { return "DROOLS_OBJECT_EDITOR"; } @Override public String getDomainName() { return DroolsDomainEditor.DROOLS_DOMAIN; } public void setReadonly( boolean readonly ) { super.setReadonly( readonly ); view.setReadonly( readonly ); } protected void loadDataObject( DataObject dataObject ) { clear(); setReadonly( true ); if ( dataObject != null ) { this.dataObject = dataObject; Annotation annotation = dataObject.getAnnotation( DroolsDomainAnnotations.ROLE_ANNOTATION ); if ( annotation != null ) { String value = annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ) != null ? annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ).toString() : UIUtil.NOT_SELECTED; view.setRole( value ); } annotation = dataObject.getAnnotation( DroolsDomainAnnotations.PROPERTY_REACTIVE_ANNOTATION ); if ( annotation != null ) { view.setPropertyReactive( Boolean.TRUE ); } annotation = dataObject.getAnnotation( DroolsDomainAnnotations.CLASS_REACTIVE_ANNOTATION ); if ( annotation != null ) { view.setClassReactive( Boolean.TRUE ); } annotation = dataObject.getAnnotation( DroolsDomainAnnotations.TYPE_SAFE_ANNOTATION ); if ( annotation != null ) { String value = annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ) != null ? annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ).toString() : UIUtil.NOT_SELECTED; view.setTypeSafe( value ); } annotation = dataObject.getAnnotation( DroolsDomainAnnotations.EXPIRES_ANNOTATION ); if ( annotation != null ) { view.setExpires( annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ).toString() ); } annotation = dataObject.getAnnotation( DroolsDomainAnnotations.JAXB_XML_ROOT_ELEMENT_ANNOTATION ); if ( annotation == null ) { // look for old style annotation. annotation = dataObject.getAnnotation( DroolsDomainAnnotations.REMOTABLE_ANNOTATION ); } if ( annotation != null ) { view.setRemotable( Boolean.TRUE ); } loadDuration( dataObject ); loadTimestamp( dataObject ); setReadonly( getContext() == null || getContext().isReadonly() ); } } private void loadDuration( DataObject dataObject ) { Annotation annotation; loadDurationSelector( dataObject ); annotation = dataObject.getAnnotation( DroolsDomainAnnotations.DURATION_ANNOTATION ); if ( annotation != null ) { String value = annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ) != null ? annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ).toString() : UIUtil.NOT_SELECTED; view.setDurationField( value ); } } private void loadTimestamp( DataObject dataObject ) { Annotation annotation; loadTimestampSelector( dataObject ); annotation = dataObject.getAnnotation( DroolsDomainAnnotations.TIMESTAMP_ANNOTATION ); if ( annotation != null ) { String value = annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ) != null ? annotation.getValue( DroolsDomainAnnotations.VALUE_PARAM ).toString() : UIUtil.NOT_SELECTED; view.setTimeStampField( value ); } } // Event observers private void onDataObjectFieldCreated( @Observes DataObjectFieldCreatedEvent event ) { updateFieldDependentSelectors( event, event.getCurrentDataObject(), event.getCurrentField() ); } private void onDataObjectFieldChange( @Observes DataObjectFieldChangeEvent event ) { updateFieldDependentSelectors( event, event.getCurrentDataObject(), event.getCurrentField() ); } private void onDataObjectFieldDeleted( @Observes DataObjectFieldDeletedEvent event ) { updateFieldDependentSelectors( event, event.getCurrentDataObject(), event.getCurrentField() ); } private void updateFieldDependentSelectors( DataModelerEvent event, DataObject currentDataObject, ObjectProperty currentField ) { if ( event.isFromContext( context != null ? context.getContextId() : null ) && getDataObject() == currentDataObject ) { loadDuration( getDataObject() ); loadTimestamp( getDataObject() ); } } @Override public void onRoleChange() { if ( getDataObject() != null ) { final String newRole = UIUtil.NOT_SELECTED.equals( view.getRole() ) ? null : view.getRole(); commandBuilder.buildDataObjectAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.ROLE_ANNOTATION, DroolsDomainAnnotations.VALUE_PARAM, newRole, true ).execute(); } } @Override public void onTypeSafeChange() { if ( getDataObject() != null ) { final String newTypeSafeValue = UIUtil.NOT_SELECTED.equals( view.getTypeSafe() ) ? null : view.getTypeSafe(); commandBuilder.buildDataObjectAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.TYPE_SAFE_ANNOTATION, DroolsDomainAnnotations.VALUE_PARAM, newTypeSafeValue, true ).execute(); } } @Override public void onTimeStampFieldChange() { if ( getDataObject() != null ) { final String newTimestampValue = UIUtil.NOT_SELECTED.equals( view.getTimeStampField() ) ? null : view.getTimeStampField(); commandBuilder.buildDataObjectAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.TIMESTAMP_ANNOTATION, DroolsDomainAnnotations.VALUE_PARAM, newTimestampValue, true ).execute(); } } @Override public void onDurationFieldChange() { if ( getDataObject() != null ) { final String newDurationValue = UIUtil.NOT_SELECTED.equals( view.getDurationField() ) ? null : view.getDurationField(); commandBuilder.buildDataObjectAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.DURATION_ANNOTATION, DroolsDomainAnnotations.VALUE_PARAM, newDurationValue, true ).execute(); } } @Override public void onPropertyReactiveChange() { if ( getDataObject() != null ) { final Boolean isChecked = view.getPropertyReactive(); commandBuilder.buildDataObjectAddOrRemoveAnnotationCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.PROPERTY_REACTIVE_ANNOTATION, isChecked ).execute(); if ( isChecked ) { commandBuilder.buildDataObjectRemoveAnnotationCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.CLASS_REACTIVE_ANNOTATION ).execute(); view.setClassReactive( false ); } } } @Override public void onClassReactiveChange() { if ( getDataObject() != null ) { final Boolean isChecked = view.getClassReactive(); commandBuilder.buildDataObjectAddOrRemoveAnnotationCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.CLASS_REACTIVE_ANNOTATION, isChecked ).execute(); if ( isChecked ) { commandBuilder.buildDataObjectRemoveAnnotationCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.PROPERTY_REACTIVE_ANNOTATION ).execute(); view.setPropertyReactive( false ); } } } @Override public void onExpiresChange() { if ( getDataObject() != null ) { view.setExpiresOnError( false ); final Command afterCloseCommand = new Command() { @Override public void execute() { view.setExpiresOnError( true ); view.selectAllExpiresText(); } }; final String newValue = view.getExpires(); // Otherwise validate validatorService.isValidTimerInterval( newValue, new ValidatorCallback() { @Override public void onFailure() { view.showErrorPopup( Constants.INSTANCE.validation_error_invalid_timer_expression( newValue ), null, afterCloseCommand ); } @Override public void onSuccess() { commandBuilder.buildDataObjectAnnotationValueChangeCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.EXPIRES_ANNOTATION, DroolsDomainAnnotations.VALUE_PARAM, DataModelerUtils.nullTrim( newValue ), true ).execute(); } } ); } } @Override public void onRemotableChange() { if ( getDataObject() != null ) { final Boolean isChecked = view.getRemotable(); commandBuilder.buildDataObjectAddOrRemoveAnnotationCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.JAXB_XML_ROOT_ELEMENT_ANNOTATION, isChecked ).execute(); //remove the old style annotation. commandBuilder.buildDataObjectRemoveAnnotationCommand( getContext(), getName(), getDataObject(), DroolsDomainAnnotations.REMOTABLE_ANNOTATION ).execute(); } } private void loadDurationSelector( DataObject dataObject ) { if ( dataObject == null ) { return; } List<String> types = new ArrayList<String>(); types.add( "short" ); types.add( "int" ); types.add( "long" ); types.add( "java.lang.Short" ); types.add( "java.lang.Integer" ); types.add( "java.lang.Long" ); String defaultValue = null; Annotation annotation = dataObject.getAnnotation( DroolsDomainAnnotations.DURATION_ANNOTATION ); if ( annotation != null ) { defaultValue = AnnotationValueHandler.getStringValue( annotation, DroolsDomainAnnotations.VALUE_PARAM ); } List<Pair<String, String>> propertyOptions = loadPropertyOptions( dataObject, types, defaultValue ); view.initDurationFieldList( propertyOptions, true ); } private void loadTimestampSelector( DataObject dataObject ) { if ( dataObject == null ) { return; } List<String> types = new ArrayList<String>(); types.add( "long" ); types.add( "java.lang.Long" ); types.add( "java.util.Date" ); types.add( "java.sql.Timestamp" ); String defaultValue = null; Annotation annotation = dataObject.getAnnotation( DroolsDomainAnnotations.TIMESTAMP_ANNOTATION ); if ( annotation != null ) { defaultValue = AnnotationValueHandler.getStringValue( annotation, DroolsDomainAnnotations.VALUE_PARAM ); } List<Pair<String, String>> propertyOptions = loadPropertyOptions( dataObject, types, defaultValue ); view.initTimeStampFieldList( propertyOptions, true ); } private List<Pair<String, String>> loadPropertyOptions( DataObject dataObject, List<String> types, String defaultValue ) { List<Pair<String, String>> propertyOptions = new ArrayList<Pair<String, String>>( ); if ( dataObject != null ) { List<ObjectProperty> properties = DataModelerUtils.filterPropertiesByType( dataObject.getProperties(), types, true ); SortedMap<String, String> propertyNames = new TreeMap<String, String>(); for ( ObjectProperty property : properties ) { propertyNames.put( property.getName(), property.getName() ); } if ( defaultValue != null && !"".equals( defaultValue ) ) { propertyNames.put( defaultValue, defaultValue ); } for ( Map.Entry<String, String> propertyName : propertyNames.entrySet() ) { propertyOptions.add( new Pair( propertyName.getKey(), propertyName.getValue() ) ); } } return propertyOptions; } public void clear() { view.setRole( UIUtil.NOT_SELECTED ); view.setClassReactive( false ); view.setPropertyReactive( false ); view.setClassReactive( false ); view.setTypeSafe( UIUtil.NOT_SELECTED ); view.setExpires( null ); view.setExpiresOnError( false ); view.setDurationField( UIUtil.NOT_SELECTED ); view.setTimeStampField( UIUtil.NOT_SELECTED ); view.setRemotable( false ); } }