/******************************************************************************* * 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); } } } }