View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.eclipse.ui.jcr;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import javax.jcr.Node;
22  import javax.jcr.NodeIterator;
23  import javax.jcr.RepositoryException;
24  import javax.jcr.Session;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.argeo.eclipse.ui.AbstractTreeContentProvider;
29  import org.argeo.eclipse.ui.EclipseUiException;
30  
31  /** Canonical implementation of tree content provider manipulating JCR nodes. */
32  public abstract class AbstractNodeContentProvider extends
33  		AbstractTreeContentProvider {
34  	private static final long serialVersionUID = -4905836490027272569L;
35  
36  	private final static Log log = LogFactory
37  			.getLog(AbstractNodeContentProvider.class);
38  
39  	private Session session;
40  
41  	public AbstractNodeContentProvider(Session session) {
42  		this.session = session;
43  	}
44  
45  	/**
46  	 * Whether this path is a base path (and thus has no parent). By default it
47  	 * returns true if path is '/' (root node)
48  	 */
49  	protected Boolean isBasePath(String path) {
50  		// root node
51  		return path.equals("/");
52  	}
53  
54  	@Override
55  	public Object[] getChildren(Object element) {
56  		Object[] children;
57  		if (element instanceof Node) {
58  			try {
59  				Node node = (Node) element;
60  				children = getChildren(node);
61  			} catch (RepositoryException e) {
62  				throw new EclipseUiException("Cannot get children of " + element, e);
63  			}
64  		} else if (element instanceof WrappedNode) {
65  			WrappedNode wrappedNode = (WrappedNode) element;
66  			try {
67  				children = getChildren(wrappedNode.getNode());
68  			} catch (RepositoryException e) {
69  				throw new EclipseUiException("Cannot get children of "
70  						+ wrappedNode, e);
71  			}
72  		} else if (element instanceof NodesWrapper) {
73  			NodesWrapper node = (NodesWrapper) element;
74  			children = node.getChildren();
75  		} else {
76  			children = super.getChildren(element);
77  		}
78  
79  		children = sort(element, children);
80  		return children;
81  	}
82  
83  	/** Do not sort by default. To be overidden to provide custom sort. */
84  	protected Object[] sort(Object parent, Object[] children) {
85  		return children;
86  	}
87  
88  	/**
89  	 * To be overridden in order to filter out some nodes. Does nothing by
90  	 * default. The provided list is a temporary one and can thus be modified
91  	 * directly . (e.g. via an iterator)
92  	 */
93  	protected List<Node> filterChildren(List<Node> children)
94  			throws RepositoryException {
95  		return children;
96  	}
97  
98  	protected Object[] getChildren(Node node) throws RepositoryException {
99  		List<Node> nodes = new ArrayList<Node>();
100 		for (NodeIterator nit = node.getNodes(); nit.hasNext();)
101 			nodes.add(nit.nextNode());
102 		nodes = filterChildren(nodes);
103 		return nodes.toArray();
104 	}
105 
106 	@Override
107 	public Object getParent(Object element) {
108 		if (element instanceof Node) {
109 			Node node = (Node) element;
110 			try {
111 				String path = node.getPath();
112 				if (isBasePath(path))
113 					return null;
114 				else
115 					return node.getParent();
116 			} catch (RepositoryException e) {
117 				log.warn("Cannot get parent of " + element + ": " + e);
118 				return null;
119 			}
120 		} else if (element instanceof WrappedNode) {
121 			WrappedNode wrappedNode = (WrappedNode) element;
122 			return wrappedNode.getParent();
123 		} else if (element instanceof NodesWrapper) {
124 			NodesWrapper nodesWrapper = (NodesWrapper) element;
125 			return this.getParent(nodesWrapper.getNode());
126 		}
127 		return super.getParent(element);
128 	}
129 
130 	@Override
131 	public boolean hasChildren(Object element) {
132 		try {
133 			if (element instanceof Node) {
134 				Node node = (Node) element;
135 				return node.hasNodes();
136 			} else if (element instanceof WrappedNode) {
137 				WrappedNode wrappedNode = (WrappedNode) element;
138 				return wrappedNode.getNode().hasNodes();
139 			} else if (element instanceof NodesWrapper) {
140 				NodesWrapper nodesWrapper = (NodesWrapper) element;
141 				return nodesWrapper.hasChildren();
142 			}
143 
144 		} catch (RepositoryException e) {
145 			throw new EclipseUiException("Cannot check whether " + element
146 					+ " has children", e);
147 		}
148 		return super.hasChildren(element);
149 	}
150 
151 	public Session getSession() {
152 		return session;
153 	}
154 }