/****************************************************************************** * Copyright (c) 2016 Oracle * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Konstantin Komissarchik - initial implementation and ongoing maintenance ******************************************************************************/ package org.eclipse.sapphire.samples.sqlschema; import org.eclipse.sapphire.Event; import org.eclipse.sapphire.FilteredListener; import org.eclipse.sapphire.Listener; import org.eclipse.sapphire.LocalizableText; import org.eclipse.sapphire.PropertyContentEvent; import org.eclipse.sapphire.ReferenceValue; import org.eclipse.sapphire.Text; import org.eclipse.sapphire.modeling.Status; import org.eclipse.sapphire.samples.sqlschema.ForeignKey.ColumnAssociation; import org.eclipse.sapphire.services.ReferenceService; import org.eclipse.sapphire.services.ValidationService; /** * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a> */ public final class FKColumnAssociationValidator extends ValidationService { @Text( "Foreign key column types do not match" ) private static LocalizableText error; static { LocalizableText.init( FKColumnAssociationValidator.class ); } private ColumnAssociation association; private ReferenceService<?> localColumnReferenceService; private Column localColumn; private ReferenceService<?> referencedColumnReferenceService; private Column referencedColumn; private Listener referenceServiceListener; private Listener columnTypeListener; @Override protected void initValidationService() { this.referenceServiceListener = new Listener() { @Override public void handle( final Event event ) { refresh(); } }; this.columnTypeListener = new FilteredListener<PropertyContentEvent>() { @Override protected void handleTypedEvent( final PropertyContentEvent event ) { refresh(); } }; this.association = context( ColumnAssociation.class ); this.localColumnReferenceService = this.association.getLocalColumn().service( ReferenceService.class ); this.localColumnReferenceService.attach( this.referenceServiceListener ); this.referencedColumnReferenceService = this.association.getReferencedColumn().service( ReferenceService.class ); this.referencedColumnReferenceService.attach( this.referenceServiceListener ); } @Override protected Status compute() { this.localColumn = column( this.association.getLocalColumn(), this.localColumn ); this.referencedColumn = column( this.association.getReferencedColumn(), this.referencedColumn ); if( this.localColumn != null && this.referencedColumn != null ) { final ColumnType localColumnType = this.localColumn.getType().content(); final ColumnType referencedColumnType = this.referencedColumn.getType().content(); if( localColumnType != null && referencedColumnType != null && localColumnType != referencedColumnType ) { return Status.createErrorStatus( error.text() ); } } return Status.createOkStatus(); } private Column column( final ReferenceValue<String,Column> property, final Column cached ) { final Column current = property.target(); if( cached != current ) { if( cached != null && ! cached.disposed() ) { cached.getType().detach( this.columnTypeListener ); } if( current != null ) { current.getType().attach( this.columnTypeListener ); } } return current; } @Override public void dispose() { this.association = null; this.localColumnReferenceService.detach( this.referenceServiceListener ); this.localColumnReferenceService = null; this.referencedColumnReferenceService.detach( this.referenceServiceListener ); this.referencedColumnReferenceService = null; this.referenceServiceListener = null; if( this.localColumn != null && ! this.localColumn.disposed() ) { this.localColumn.getType().detach( this.columnTypeListener ); this.localColumn = null; } if( this.referencedColumn != null && ! this.referencedColumn.disposed() ) { this.referencedColumn.getType().detach( this.columnTypeListener ); this.referencedColumn = null; } this.columnTypeListener = null; } }