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.slc.client.ui.dist.editors;
17  
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.List;
21  import java.util.Map;
22  
23  import javax.jcr.Node;
24  import javax.jcr.NodeIterator;
25  import javax.jcr.RepositoryException;
26  import javax.jcr.Session;
27  import javax.jcr.query.QueryManager;
28  import javax.jcr.query.QueryResult;
29  import javax.jcr.query.qom.Ordering;
30  import javax.jcr.query.qom.QueryObjectModel;
31  import javax.jcr.query.qom.QueryObjectModelFactory;
32  import javax.jcr.query.qom.Selector;
33  
34  import org.argeo.cms.ui.workbench.util.CommandUtils;
35  import org.argeo.jcr.JcrUtils;
36  import org.argeo.slc.SlcException;
37  import org.argeo.slc.SlcNames;
38  import org.argeo.slc.SlcTypes;
39  import org.argeo.slc.client.ui.dist.DistConstants;
40  import org.argeo.slc.client.ui.dist.DistImages;
41  import org.argeo.slc.client.ui.dist.commands.OpenModuleEditor;
42  import org.argeo.slc.repo.RepoConstants;
43  import org.eclipse.jface.viewers.ColumnLabelProvider;
44  import org.eclipse.jface.viewers.DoubleClickEvent;
45  import org.eclipse.jface.viewers.IDoubleClickListener;
46  import org.eclipse.jface.viewers.IStructuredSelection;
47  import org.eclipse.jface.viewers.ITreeContentProvider;
48  import org.eclipse.jface.viewers.TreeViewer;
49  import org.eclipse.jface.viewers.Viewer;
50  import org.eclipse.swt.SWT;
51  import org.eclipse.swt.graphics.Image;
52  import org.eclipse.swt.layout.FillLayout;
53  import org.eclipse.swt.widgets.Composite;
54  import org.eclipse.swt.widgets.Tree;
55  import org.eclipse.swt.widgets.TreeColumn;
56  import org.eclipse.ui.forms.IManagedForm;
57  import org.eclipse.ui.forms.editor.FormEditor;
58  import org.eclipse.ui.forms.editor.FormPage;
59  import org.eclipse.ui.forms.widgets.ScrolledForm;
60  
61  /**
62   * Expose Maven artifacts of a given workspace as a tree. Artifacts are grouped
63   * by Maven group.
64   */
65  public class DistWkspBrowserPage extends FormPage implements DistConstants,
66  		RepoConstants {
67  	// private final static Log log = LogFactory
68  	// .getLog(ArtifactsBrowserPage.class);
69  
70  	final static String PAGE_ID = "artifactsBrowserPage";
71  
72  	// Business object
73  	private Session session;
74  
75  	// This page widgets
76  	private TreeViewer artifactTreeViewer;
77  
78  	public DistWkspBrowserPage(FormEditor editor, String title, Session session) {
79  		super(editor, PAGE_ID, title);
80  		this.session = session;
81  	}
82  
83  	@Override
84  	protected void createFormContent(IManagedForm managedForm) {
85  		try {
86  			ScrolledForm form = managedForm.getForm();
87  			Composite parent = form.getBody();
88  			parent.setLayout(new FillLayout());
89  			createMavenBrowserPart(parent);
90  			getEditor().getSite().setSelectionProvider(artifactTreeViewer);
91  		} catch (RepositoryException e) {
92  			throw new SlcException("Cannot create artifact browser page", e);
93  		}
94  	}
95  
96  	/** Aether specific browser for the current workspace */
97  	private void createMavenBrowserPart(Composite parent)
98  			throws RepositoryException {
99  
100 		int style = SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL
101 				| SWT.FULL_SELECTION | SWT.BORDER;
102 		
103 		Tree tree = new Tree(parent, style);
104 		createColumn(tree, "Maven browser", SWT.LEFT, 450);
105 		tree.setLinesVisible(true);
106 		tree.setHeaderVisible(true);
107 
108 		artifactTreeViewer = new TreeViewer(tree);
109 
110 		artifactTreeViewer.setLabelProvider(new ColumnLabelProvider() {
111 			private static final long serialVersionUID = 2648269889876058461L;
112 
113 			@Override
114 			public String getText(Object element) {
115 				Node node = (Node) element;
116 				try {
117 					if (node.isNodeType(SlcTypes.SLC_GROUP_BASE))
118 						return JcrUtils.get((Node) element,
119 								SlcNames.SLC_GROUP_BASE_ID);
120 					else if (node.isNodeType(SlcTypes.SLC_ARTIFACT_BASE))
121 						return JcrUtils.get((Node) element,
122 								SlcNames.SLC_ARTIFACT_ID);
123 					else
124 						return node.getName();
125 				} catch (RepositoryException e) {
126 					throw new SlcException("Cannot browse artifacts", e);
127 				}
128 			}
129 
130 			@Override
131 			public Image getImage(Object element) {
132 				Node node = (Node) element;
133 				try {
134 
135 					if (node.isNodeType(SlcTypes.SLC_GROUP_BASE))
136 						return DistImages.IMG_GROUP_BASE;
137 					else if (node.isNodeType(SlcTypes.SLC_ARTIFACT_BASE))
138 						return DistImages.IMG_ARTIFACT_BASE;
139 					else if (node
140 							.isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE))
141 						return DistImages.IMG_ARTIFACT_VERSION_BASE;
142 					else
143 						return null;
144 				} catch (RepositoryException e) {
145 					throw new SlcException("Cannot get images for artifacts", e);
146 				}
147 			}
148 		});
149 
150 		artifactTreeViewer.setContentProvider(new ITreeContentProvider() {
151 			private static final long serialVersionUID = -2381555428857519326L;
152 
153 			public void dispose() {
154 			}
155 
156 			public void inputChanged(Viewer viewer, Object oldInput,
157 					Object newInput) {
158 			}
159 
160 			public Object[] getElements(Object inputElement) {
161 				try {
162 					List<Node> nodes = JcrUtils.nodeIteratorToList(listNodes(
163 							SlcTypes.SLC_GROUP_BASE, SlcNames.SLC_NAME));
164 					return nodes.toArray();
165 				} catch (RepositoryException e) {
166 					throw new SlcException("Cannot list children Nodes", e);
167 				}
168 			}
169 
170 			public Object[] getChildren(Object parentElement) {
171 				// Only 3 levels for the time being
172 				try {
173 					Node pNode = (Node) parentElement;
174 					if (pNode.isNodeType(SlcTypes.SLC_GROUP_BASE)) {
175 						return getArtifactBase(pNode,
176 								SlcTypes.SLC_ARTIFACT_BASE);
177 					} else if (pNode.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
178 						return getArtifactBase(pNode,
179 								SlcTypes.SLC_ARTIFACT_VERSION_BASE);
180 					}
181 					return null;
182 				} catch (RepositoryException e) {
183 					throw new SlcException("Cannot list children Nodes", e);
184 				}
185 			}
186 
187 			// Helper to get children because current version of Jackrabbit is
188 			// buggy in remote
189 			private Object[] getArtifactBase(Node parent, String nodeType)
190 					throws RepositoryException {
191 				List<Node> nodes = new ArrayList<Node>();
192 				NodeIterator ni = parent.getNodes();
193 				while (ni.hasNext()) {
194 					Node node = ni.nextNode();
195 					if (node.isNodeType(nodeType))
196 						nodes.add(node);
197 				}
198 				return nodes.toArray();
199 			}
200 
201 			public Object getParent(Object element) {
202 				return null;
203 			}
204 
205 			public boolean hasChildren(Object element) {
206 				try {
207 					Node pNode = (Node) element;
208 					if (pNode.isNodeType(SlcTypes.SLC_GROUP_BASE)
209 							|| pNode.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
210 						// might return true even if there is no "valid" child
211 						return pNode.hasNodes();
212 					} else
213 						return false;
214 				} catch (RepositoryException e) {
215 					throw new SlcException("Cannot check children Nodes", e);
216 				}
217 			}
218 		});
219 
220 		artifactTreeViewer.addDoubleClickListener(new DoubleClickListener());
221 
222 		artifactTreeViewer.setInput("Initialize");
223 	}
224 
225 	private class DoubleClickListener implements IDoubleClickListener {
226 
227 		public void doubleClick(DoubleClickEvent event) {
228 			Object obj = ((IStructuredSelection) event.getSelection())
229 					.getFirstElement();
230 			if (obj instanceof Node) {
231 				Node node = (Node) obj;
232 				try {
233 					if (node.isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) {
234 						NodeIterator nit = node.getNodes();
235 						while (nit.hasNext()) {
236 							Node curr = nit.nextNode();
237 							if (curr.isNodeType(SlcTypes.SLC_ARTIFACT)) {
238 								node = curr;
239 								break;
240 							}
241 						}
242 					}
243 
244 					if (node.isNodeType(SlcTypes.SLC_ARTIFACT)) {
245 						DistWkspEditorInput dwip = (DistWkspEditorInput) getEditorInput();
246 						Map<String, String> params = new HashMap<String, String>();
247 						params.put(OpenModuleEditor.PARAM_REPO_NODE_PATH,
248 								dwip.getRepoNodePath());
249 						params.put(OpenModuleEditor.PARAM_REPO_URI,
250 								dwip.getUri());
251 						params.put(OpenModuleEditor.PARAM_WORKSPACE_NAME,
252 								dwip.getWorkspaceName());
253 						String path = node.getPath();
254 						params.put(OpenModuleEditor.PARAM_MODULE_PATH, path);
255 						CommandUtils.callCommand(OpenModuleEditor.ID, params);
256 					}
257 				} catch (RepositoryException re) {
258 					throw new SlcException("Cannot get path for node " + node
259 							+ " while setting parameters for "
260 							+ "command OpenModuleEditor", re);
261 				}
262 
263 			}
264 		}
265 	}
266 
267 	private static TreeColumn createColumn(Tree parent, String name, int style,
268 			int width) {
269 		TreeColumn result = new TreeColumn(parent, style);
270 		result.setText(name);
271 		result.setWidth(width);
272 		result.setMoveable(true);
273 		result.setResizable(true);
274 		return result;
275 	}
276 
277 	private NodeIterator listNodes(String nodeType, String orderBy)
278 			throws RepositoryException {
279 		QueryManager queryManager = session.getWorkspace().getQueryManager();
280 		QueryObjectModelFactory factory = queryManager.getQOMFactory();
281 
282 		final String nodeSelector = "nodes";
283 		Selector source = factory.selector(nodeType, nodeSelector);
284 
285 		Ordering order = factory.ascending(factory.propertyValue(nodeSelector,
286 				orderBy));
287 		Ordering[] orderings = { order };
288 
289 		QueryObjectModel query = factory.createQuery(source, null, orderings,
290 				null);
291 
292 		QueryResult result = query.execute();
293 
294 		return result.getNodes();
295 	}
296 
297 	
298 }