/*
* Copyright 2016 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.dmn.core.compiler;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.kie.dmn.model.v1_1.ItemDefinition;
public class ItemDefinitionDependenciesSorter {
private final String modelNamespace;
public ItemDefinitionDependenciesSorter(String modelNamespace) {
this.modelNamespace = modelNamespace;
}
/**
* Return a new list of ItemDefinition sorted by dependencies (required dependencies comes first)
*/
public List<ItemDefinition> sort(List<ItemDefinition> ins) {
// this method approximates a topological sort.
List<ItemDefinition> todos = new ArrayList<>(ins);
List<ItemDefinition> ordered = new ArrayList<>(ins.size());
while ( todos.size() > 0 ) {
ItemDefinition c1 = todos.get(0);
for ( int i = 1; i < todos.size(); i++) {
ItemDefinition other = todos.get(i);
QName otherQName = new QName(modelNamespace, other.getName());
if ( recurseFind(c1, otherQName) ) {
c1 = other;
}
}
ordered.add(c1);
todos.remove(c1);
}
return ordered;
}
private static boolean recurseFind(ItemDefinition o1, QName qname2) {
if ( o1.getTypeRef() != null ) {
if ( o1.getTypeRef().equals(qname2) ) {
return true;
}
}
for ( ItemDefinition ic : o1.getItemComponent() ) {
if ( recurseFind(ic, qname2) ) {
return true;
}
}
return false;
}
private static boolean directFind(ItemDefinition o1, QName qname2) {
if ( o1.getTypeRef() != null ) {
if ( o1.getTypeRef().equals(qname2) ) {
return true;
}
}
for ( ItemDefinition ic : o1.getItemComponent() ) {
if ( ic.getTypeRef() == null ) {
// anon inner type
if ( directFind(ic, qname2) ) {
return true;
}
} else if ( ic.getTypeRef().equals(qname2) ) {
return true;
}
}
return false;
}
public static void displayDependencies(List<ItemDefinition> ins, String namespaceURI) {
for ( ItemDefinition in : ins ) {
System.out.println(in.getName());
List<ItemDefinition> others = new ArrayList<>(ins);
others.remove(in);
for ( ItemDefinition other : others ) {
QName otherQName = new QName(namespaceURI, other.getName());
if ( directFind(in, otherQName) ) {
System.out.println(" direct depends on: "+other.getName());
} else if ( recurseFind(in, otherQName) ) {
System.out.println(" indir. depends on: "+other.getName());
}
}
}
}
}