/*******************************************************************************
* 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.model.ui.texteditors;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.jboss.tools.common.model.XModelObject;
public class XMLModelObjectFinder {
class Chain {
Chain child;
String name;
int index;
}
public XModelObject findModelObject(IndexedRegion region, XModelObject root) {
if(root == null) return null;
if(!(region instanceof Node)) return null;
Node node = (Node)region;
while(node != null && !(node instanceof Element)) {
node = (Node)node.getParentNode();
}
if(node == null) return null;
Chain c = new Chain();
c.name = node.getNodeName();
while(node != null) {
Node sibling = node;
while(sibling != null) {
sibling = sibling.getPreviousSibling();
if(sibling instanceof Element && c.name.equals(sibling.getNodeName())) c.index++;
}
node = (Node)node.getParentNode();
if(!(node instanceof Element)) break;
Chain c1 = new Chain();
c1.name = node.getNodeName();
c1.child = c;
c = c1;
}
return findModelObject(c, root);
}
private XModelObject findModelObject(Chain chain, XModelObject o) {
if(chain == null) return o;
String n = o.getModelEntity().getXMLSubPath();
if(n.equals(chain.name)) {
return findModelObject(chain.child, o);
}
String childEntity = getChildEntity(chain.name, o);
if(childEntity != null) {
XModelObject[] cs = o.getChildren();
if(cs.length <= chain.index) {
XModelObject c = findModelObject(chain.child, o);
if(c != null) return c;
return o;
}
int index = -1;
for (int i = 0; i < cs.length; i++) {
if(chain.name != null && chain.name.equals(cs[i].getModelEntity().getXMLSubPath())) {
index++;
if(index == chain.index) {
return findModelObject(chain.child, cs[i]);
}
}
}
XModelObject c = findModelObject(chain.child, o);
if(c != null) return c;
return o;
} else {
XModelObject[] cs = o.getChildren();
for (int i = 0; i < cs.length; i++) {
if(cs[i].getModelEntity().getXMLSubPath().length() > 0) continue;
XModelObject res = findModelObject(chain, cs[i]);
if(res != cs[i]) return res;
}
XModelObject x = o.getChildByPath(chain.name + ((chain.index == 0) ? "" : chain.index));
if(x != null) {
XModelObject res = findModelObject(chain.child, x);
if(res != null) {
return res;
} else {
return x;
}
}
return o;
}
}
private String getChildEntity(String nodename, XModelObject o) {
return o.getModelEntity().getChildByXML(nodename);
}
}