/*
* 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.
*
* 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.core.util;
import java.io.Externalizable;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public abstract class AbstractCodedHierarchyImpl<T> extends AbstractBitwiseHierarchyImpl<T,HierNode<T>> implements CodedHierarchy<T>, Externalizable {
protected abstract HierNode<T> getNode( T name );
public void addMember( T val, BitSet key ) {
if ( hasKey( key ) ) {
HierNode<T> node = line.get( key );
node.setValue( val );
} else {
HierNode<T> node = new HierNode<T>( val, key );
Collection<HierNode<T>> infs = gcsBorderNodes( key, false );
Collection<HierNode<T>> sups = lcsBorderNodes( key, false );
for ( HierNode<T> child : infs ) {
if ( child != null ) {
child.getParents().add( node );
child.getParents().removeAll( sups );
node.getChildren().add( child );
}
}
for ( HierNode<T> parent : sups ) {
if ( parent != null ) {
parent.getChildren().add( node );
parent.getChildren().removeAll( infs );
node.getParents().add( parent );
}
}
add( node );
// System.out.println( " Added inst node " + node );
// System.out.println( " \t parents " + parents( key ) );
// System.out.println( " \t children " + children( key ) );
}
}
public void removeMember( T val ) {
if ( val == null ) {
return;
}
BitSet key = getCode( val );
removeMember( key );
}
public void removeMember( BitSet key ) {
if ( ! hasKey( key ) ) {
return;
} else {
HierNode<T> node = getNodeByKey( key );
Collection<HierNode<T>> children = node.getChildren();
Collection<HierNode<T>> parents = node.getParents();
for ( HierNode<T> child : children ) {
child.getParents().remove( node );
child.getParents().addAll( parents );
}
for ( HierNode<T> parent : parents ) {
parent.getChildren().remove( node );
parent.getChildren().addAll( children );
}
remove( node );
}
}
protected Collection<T> parentValues( HierNode<T> node ) {
if ( node == null ) {
return Collections.EMPTY_LIST;
}
List<T> p = new ArrayList<T>( node.getParents().size() );
for ( HierNode<T> parent : node.getParents() ) {
p.add( parent.getValue() );
}
return p;
}
public Collection<T> ancestors( T x ) {
HierNode<T> node = getNode(x);
return ancestorValues( node );
}
public Collection<T> ancestors( BitSet key ) {
HierNode<T> node = getNodeByKey(key);
return ancestorValues( node );
}
protected Collection<T> ancestorValues( HierNode<T> node ) {
if ( node == null ) {
return Collections.EMPTY_SET;
}
Set<T> ancestors = new HashSet<T>();
Collection<HierNode<T>> parents = node.getParents();
for ( HierNode<T> p : parents ) {
ancestors.add( p.getValue() );
ancestors.addAll( ancestors(p.getValue()) );
}
return ancestors;
}
protected Set<HierNode<T>> ancestorNodes( HierNode<T> x ) {
Set<HierNode<T>> ancestors = new HashSet<HierNode<T>>();
Collection<HierNode<T>> parents = x.getParents();
ancestors.addAll( parents );
for ( HierNode<T> p : parents ) {
ancestors.addAll( ancestorNodes( p ) );
}
return ancestors;
}
protected Collection<T> childrenValues( HierNode<T> node ) {
if ( node == null ) {
return Collections.EMPTY_LIST;
}
List<T> c = new ArrayList<T>( node.getChildren().size() );
for ( HierNode<T> child : node.getChildren() ) {
c.add( child.getValue() );
}
return c;
}
public Collection<T> children( T x ) {
HierNode<T> node = getNode(x);
return childrenValues( node );
}
public Collection<T> children( BitSet key ) {
HierNode<T> node = getNodeByKey(key);
return childrenValues( node );
}
protected Collection<T> descendantValues( HierNode<T> node ) {
if ( node == null ) {
return Collections.EMPTY_SET;
}
Set<T> descendants = new HashSet<T>();
descendants.add( node.getValue() );
Collection<HierNode<T>> children = node.getChildren();
for ( HierNode<T> c : children ) {
descendants.add( c.getValue() );
descendants.addAll(descendants(c.getValue()));
}
return descendants;
}
public Collection<T> descendants( T y ) {
HierNode<T> node = getNode(y);
return descendantValues( node );
}
public Collection<T> descendants( BitSet key ) {
HierNode<T> node = getNodeByKey(key);
return descendantValues( node );
}
protected Set<HierNode<T>> descendantNodes( HierNode<T> y ) {
Set<HierNode<T>> descendants = new HashSet<HierNode<T>>();
descendants.add( y );
Collection<HierNode<T>> children = y.getChildren();
descendants.addAll( children );
for ( HierNode<T> c : children ) {
descendants.addAll( descendantNodes( c ) );
}
return descendants;
}
}