/* * Copyright 2012 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.drools.workbench.models.datamodel.rule; import java.util.Arrays; /** * This is a field constraint that may span multiple fields. */ public class CompositeFieldConstraint implements FieldConstraint, HasConstraints { /** * Means that any of the children can resolve to be true. */ public static final String COMPOSITE_TYPE_OR = "||"; /** * Means that ALL of the children constraints must resolve to be true. */ public static final String COMPOSITE_TYPE_AND = "&&"; /** * The type of composite that it is. */ private String compositeJunctionType = null; /** * This is the child field constraints of the composite. They may be single * constraints, or composite themselves. If this composite is it at the * "top level" - then there is no need to look at the compositeType property * (as they are all children that are "anded" together anyway in the fact * pattern that contains it). */ private FieldConstraint[] constraints = null; public CompositeFieldConstraint() { } //Note this is a bit ugly, GWT had some early limitations which required this to kind of work this way. //when generics are available, could probably switch to it, but remember this is persistent stuff //so don't want to break backwards compat (as XStream is used) public void addConstraint( final FieldConstraint constraint ) { if ( this.constraints == null ) { this.constraints = new FieldConstraint[ 1 ]; this.constraints[ 0 ] = constraint; } else { final FieldConstraint[] newList = new FieldConstraint[ this.constraints.length + 1 ]; for ( int i = 0; i < this.constraints.length; i++ ) { newList[ i ] = this.constraints[ i ]; } newList[ this.constraints.length ] = constraint; this.constraints = newList; } } //Unfortunately, this is kinda duplicate code with other methods, but with //typed arrays, and GWT, its not really possible to do anything "better" //at this point in time. public void removeConstraint( final int idx ) { //If the constraint being is a parent of another correct the other constraint's parent accordingly FieldConstraint constraintToRemove = this.constraints[ idx ]; if ( constraintToRemove instanceof SingleFieldConstraint ) { final SingleFieldConstraint sfc = (SingleFieldConstraint) constraintToRemove; FieldConstraint parent = sfc.getParent(); for ( FieldConstraint child : this.constraints ) { if ( child instanceof SingleFieldConstraint ) { SingleFieldConstraint sfcChild = (SingleFieldConstraint) child; if ( sfcChild.getParent() == constraintToRemove ) { sfcChild.setParent( parent ); break; } } } } final FieldConstraint[] newList = new FieldConstraint[ this.constraints.length - 1 ]; int newIdx = 0; for ( int i = 0; i < this.constraints.length; i++ ) { if ( i != idx ) { newList[ newIdx ] = this.constraints[ i ]; newIdx++; } } this.constraints = newList; } public FieldConstraint getConstraint( int index ) { if ( this.constraints == null ) { return null; } return this.constraints[ index ]; } public int getNumberOfConstraints() { if ( this.constraints == null ) { return 0; } return this.constraints.length; } public FieldConstraint[] getConstraints() { return constraints; } public void setConstraints( FieldConstraint[] constraints ) { this.constraints = constraints; } public String getCompositeJunctionType() { return compositeJunctionType; } public void setCompositeJunctionType( String compositeJunctionType ) { this.compositeJunctionType = compositeJunctionType; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CompositeFieldConstraint that = (CompositeFieldConstraint) o; if (compositeJunctionType != null ? !compositeJunctionType.equals(that.compositeJunctionType) : that.compositeJunctionType != null) return false; if (!Arrays.equals(constraints, that.constraints)) return false; return true; } @Override public int hashCode() { int result = compositeJunctionType != null ? compositeJunctionType.hashCode() : 0; result = ~~result; result = 31 * result + (constraints != null ? Arrays.hashCode(constraints) : 0); result = ~~result; return result; } }