/*******************************************************************************
* Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Exadel, Inc. and Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.meta.impl;
import java.util.*;
import org.w3c.dom.Element;
import org.jboss.tools.common.meta.XChild;
import org.jboss.tools.common.meta.XParents;
/**
* Builds ancestor-descendant dependencies of entities
* without loading entity details.
*
* @author glory
*/
public class XParentsImpl implements XParents, XMetaDataConstants {
private Map<String,Set<String>> parents = new HashMap<String,Set<String>>();
private Map<String,Set<String>> ancestors = new HashMap<String,Set<String>>();
public boolean isDescendant(String entity1, String entity2) {
if(!parents.containsKey(entity1)) return false;
Set as = getAncestors(entity1);
return as != null && as.contains(entity2);
}
public Set<String> getAncestors(String entity) {
Set<String> set = ancestors.get(entity);
if(set == null) {
set = new HashSet<String>();
fillAncestors(entity, set);
ancestors.put(entity, set);
}
return set;
}
void init(XModelMetaDataImpl meta) {
Iterator it = meta.getEntities().keySet().iterator();
while(it.hasNext()) {
String name = it.next().toString();
XModelEntityImpl entity = (XModelEntityImpl)meta.getEntities().get(name);
Element element = entity.element;
if(element == null) {
addParents(entity.getChildren(), name);
} else {
addParents(element, name);
ArrayList<XModelEntityExtensionImpl> l = meta.getExtensions().getExtensions(name);
if(l == null) continue;
XModelEntityExtensionImpl[] ees = l.toArray(new XModelEntityExtensionImpl[0]);
for (int k = 0; k < ees.length; k++) {
Element e1 = ees[k].element;
if(e1 == null) {
addParents(ees[k].getChildren(), name);
} else {
addParents(e1, name);
}
}
}
}
}
private void addParents(XChild[] cs, String parent) {
for (int i = 0; i < cs.length; i++) add(cs[i].getName(), parent);
}
private void addParents(Element element, String parent) {
Element e = XMetaDataLoader.getUniqueChild(element, XMODEL_CHILDREN);
if(e == null) return;
Element[] es = XMetaDataLoader.getChildrenElements(e, XMODEL_CHILD);
for (int i = 0; i < es.length; i++) {
add(es[i].getAttribute(NAME), parent);
}
}
private void add(String child, String parent) {
Set<String> ps = parents.get(child);
if(ps == null) {
ps = new HashSet<String>();
parents.put(child, ps);
}
ps.add(parent);
}
public Set getParents(String entity) {
return (Set)parents.get(entity);
}
private void fillAncestors(String entity, Set<String> set) {
Set parents = getParents(entity);
if(parents == null) return;
Iterator it = parents.iterator();
while(it.hasNext()) {
String e = it.next().toString();
if(set.contains(e)) continue;
set.add(e);
Set<String> as = ancestors.get(entity);
if(as != null) {
set.addAll(as);
} else {
fillAncestors(e, set);
}
}
}
}