blob: 93f73a2d83e7d4480842af23b4e7461f59ebbf72 [file] [log] [blame]
package org.eclipse.wst.jsdt.web.ui.views.contentoutline;
import java.util.Enumeration;
import java.util.Hashtable;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.wst.jsdt.core.IJavaElement;
import org.eclipse.wst.jsdt.core.JavaModelException;
import org.eclipse.wst.jsdt.internal.core.SourceRefElement;
import org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider;
import org.eclipse.wst.jsdt.web.core.internal.Logger;
import org.eclipse.wst.jsdt.web.core.internal.java.IJSPTranslation;
import org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation;
import org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslationAdapter;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.xml.core.internal.document.NodeImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class JSDTElementContentProvider extends StandardJavaElementContentProvider {
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider#exists(java.lang.Object)
*/
ITreeContentProvider fParentContentProvider=null;
private Object[] NO_PARENT = new Object[0];
private Hashtable parents;
public JSDTElementContentProvider(IContentProvider parentContentProvider){
if(parentContentProvider instanceof ITreeContentProvider) fParentContentProvider = (ITreeContentProvider)parentContentProvider;
parents = new Hashtable();
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider#getChildren(java.lang.Object)
*/
@Override
public Object[] getChildren(Object object) {
if(object instanceof IJavaElement) return super.getChildren(object);
System.out.println("Get Children.\n Node Name: " + ((Node)object).getNodeName() +
"\nType:\n" + ((Node)object).getNodeType() +
"# of Children:" + (((Node)object).hasChildNodes()?((Node)object).getChildNodes().getLength():0) +
"\nContents:\n"+((Node)object).getNodeValue() +
"\n--------------------------------");
Node node = (Node) object;
// && !(node.getFirstChild() instanceof JSDTJfaceNode )
if (isJSElementParent(node)) {
Object[] results = getJSElementsFromNode(node.getFirstChild());
return results;
}
return fParentContentProvider.getChildren(object);
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider#getElements(java.lang.Object)
*/
@Override
public Object[] getElements(Object object) {
if(object instanceof IJavaElement) return super.getElements(object);
if(parents.contains(object)){
NodeList list= (((pLocationMap)parents.get(object)).parent).getChildNodes();
Object obj[] = new Object[list.getLength()];
for(int i = 0;i<list.getLength();i++){
obj[i] = list.item(i);
}
return obj;
}
return fParentContentProvider.getElements(object);
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider#getParent(java.lang.Object)
*/
@Override
public Object getParent(Object element) {
if(parents.contains(element)){
return ((pLocationMap)parents.get(element)).parent;
}
if(element instanceof IJavaElement) return super.getParent(element);
return fParentContentProvider.getParent(element);
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider#hasChildren(java.lang.Object)
*/
@Override
public boolean hasChildren(Object object) {
if(object instanceof IJavaElement) return super.hasChildren(object);
Node node = (Node) object;
if ( isJSElementParent(node) ) {
/* cheaper to check parent array */
Enumeration parentEnum = parents.elements();
while(parentEnum.hasMoreElements()){
pLocationMap value = (pLocationMap)parentEnum.nextElement();
/* found a child */
if(value.parent==node) return true;
}
Object[] nodes = getJSElementsFromNode(node.getFirstChild());
return (nodes != null && nodes.length > 0);
}
return fParentContentProvider.hasChildren(object);
}
private boolean isJSElementParent(Node node) {
return (node.hasChildNodes() && node.getNodeName().equalsIgnoreCase("script"));
}
private boolean isJSElement(Object object) {
if(object instanceof IJavaElement) return true;
if (JSDTJfaceNode.hasJsPart(object))
return true;
Node node = (Node) object;
Node parent = node.getParentNode();
if (parent != null && parent.getNodeName().equalsIgnoreCase("script") && node.getNodeType() == Node.TEXT_NODE) {
return true;
}
return false;
}
class pLocationMap{
Node parent;
Position htmlLocation;
pLocationMap(Node parent, Position position){
this.parent=parent;
this.htmlLocation=position;
}
}
private IJavaElement[] getJSElementsFromNode(Node node) {
IStructuredModel model = null;
IModelManager modelManager = StructuredModelManager.getModelManager();
JSPTranslation translation = null;
IJavaElement[] result = null;
try {
if (modelManager != null) {
IStructuredDocument doc = ((NodeImpl) node).getStructuredDocument();
// model = modelManager.getExistingModelForRead(doc);
model = modelManager.getExistingModelForRead(doc);
}
IDOMModel domModel = (IDOMModel) model;
IDOMDocument xmlDoc = domModel.getDocument();
JSPTranslationAdapter translationAdapter = (JSPTranslationAdapter) xmlDoc.getAdapterFor(IJSPTranslation.class);
translation = translationAdapter.getJSPTranslation();
int startOffset = 0;
int endOffset = 0;
int type = node.getNodeType();
if (node.getNodeType() == Node.TEXT_NODE && (node instanceof NodeImpl) && translation != null) {
startOffset = ((NodeImpl) node).getStartOffset();
endOffset = ((NodeImpl) node).getEndOffset();
result = translation.getElementsFromJspRange(startOffset, endOffset,true);
}
if (result == null)
return null;
} catch (Exception e) {
Logger.logException(e);
} finally {
if (model != null) {
// model.changedModel();
model.releaseFromRead();
}
}
//nodes = new JSDTJfaceNode[result.length];
// JSDTJfaceNode parentJsNode = new JSDTJfaceNode(node.getParentNode(),false);
// //model.aboutToChangeModel();
// JSDTJfaceNode parentJsNode;
//
// if(!(parentnode instanceof JSDTJfaceNode)){
// parentJsNode = new JSDTJfaceNode(parentnode,false);
// }else{
// parentJsNode = (JSDTJfaceNode)parentnode;
//
// }
// parentJsNode.removeChildNodes();
// int offset = startOffset;
/* build the node list and append to parent */
for (int i = 0; i < result.length; i++) {
// nodes[i] = new JSDTJfaceNode(parentJsNode, true);
int htmllength = 0;
int htmloffset = 0;
Position position=null;
try {
htmllength = ((SourceRefElement) (result[i])).getSourceRange().getLength();
htmloffset = translation.getJspOffset(((SourceRefElement) (result[i])).getSourceRange().getOffset());
position = new Position(htmloffset, htmllength);
} catch (JavaModelException e) {
e.printStackTrace();
}
// int adjustedLength =
// (i==result.length-1)?(-offset):htmlLength;
// nodes[i].setJsPart(result[i], new Position(htmloffset, htmllength));
//nodes[i].addAdapter(this);
// parentJsNode.appendChild(nodes[i]);
parents.put(result[i], new pLocationMap(node,position));
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// // TODO Auto-generated method stub
// System.out.println("Umiplement method inputChanged" );
// //super.inputChanged(viewer, oldInput, newInput);
// if(oldInput instanceof JSDTJfaceNode){
// if(newInput instanceof JSDTJfaceNode){
// super.inputChanged(viewer, oldInput, newInput);
// }
// }
if(oldInput!=null && parents.contains(oldInput)) parents.remove(oldInput);
fParentContentProvider.inputChanged(viewer, oldInput, newInput);
}
public ISelection getSelection(TreeViewer viewer, ISelection selection) {
if (selection instanceof StructuredSelection) {
StructuredSelection ss = (StructuredSelection) selection;
if(ss==null) return null;
Object firstElement = ss.getFirstElement();
if (isJSElement(firstElement))
return new StructuredSelection(firstElement);
if (isJSElementParent((Node) firstElement))
return new StructuredSelection(getJSElementsFromNode(((Node) firstElement).getFirstChild()));
}
return null;
}
}