1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.team.ui;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Iterator;
20 import org.eclipse.jface.action.GroupMarker;
21 import org.eclipse.jface.action.IMenuListener;
22 import org.eclipse.jface.action.IMenuManager;
23 import org.eclipse.jface.action.MenuManager;
24 import org.eclipse.jface.layout.GridDataFactory;
25 import org.eclipse.jface.layout.TreeColumnLayout;
26 import org.eclipse.jface.resource.JFaceResources;
27 import org.eclipse.jface.resource.LocalResourceManager;
28 import org.eclipse.jface.viewers.ColumnLabelProvider;
29 import org.eclipse.jface.viewers.ColumnWeightData;
30 import org.eclipse.jface.viewers.ITreeContentProvider;
31 import org.eclipse.jface.viewers.LabelProvider;
32 import org.eclipse.jface.viewers.TreeViewer;
33 import org.eclipse.jface.viewers.TreeViewerColumn;
34 import org.eclipse.jface.viewers.Viewer;
35 import org.eclipse.jface.viewers.ViewerCell;
36 import org.eclipse.swt.SWT;
37 import org.eclipse.swt.graphics.Image;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.swt.widgets.Control;
40 import org.eclipse.swt.widgets.Menu;
41 import org.eclipse.swt.widgets.Shell;
42 import org.eclipse.ui.IMemento;
43 import org.eclipse.ui.IViewSite;
44 import org.eclipse.ui.IWorkbenchActionConstants;
45 import org.eclipse.ui.IWorkbenchPartSite;
46 import org.eclipse.ui.IWorkbenchSite;
47 import org.eclipse.ui.PartInitException;
48 import org.eclipse.ui.part.IPageSite;
49 import org.eclipse.ui.part.ViewPart;
50 import org.simantics.Simantics;
51 import org.simantics.browsing.ui.GraphExplorer;
52 import org.simantics.browsing.ui.graph.impl.SessionContextInputSource;
53 import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver;
54 import org.simantics.browsing.ui.swt.GraphExplorerFactory;
55 import org.simantics.browsing.ui.swt.ViewArgumentUtils;
56 import org.simantics.databoard.Bindings;
57 import org.simantics.db.ChangeSetIdentifier;
58 import org.simantics.db.ReadGraph;
59 import org.simantics.db.Resource;
60 import org.simantics.db.Session;
61 import org.simantics.db.exception.DatabaseException;
62 import org.simantics.db.management.ISessionContext;
63 import org.simantics.db.management.ISessionContextChangedListener;
64 import org.simantics.db.management.ISessionContextProvider;
65 import org.simantics.db.management.SessionContextChangedEvent;
66 import org.simantics.db.request.Read;
67 import org.simantics.layer0.Layer0;
68 import org.simantics.project.ProjectKeys;
69 import org.simantics.team.internal.Images;
70 import org.simantics.ui.SimanticsUI;
71 import org.simantics.utils.datastructures.disposable.DisposeState;
72 import org.simantics.utils.datastructures.hints.HintListenerAdapter;
73 import org.simantics.utils.datastructures.hints.HintTracker;
74 import org.simantics.utils.datastructures.hints.IHintContext.Key;
75 import org.simantics.utils.datastructures.hints.IHintListener;
76 import org.simantics.utils.datastructures.hints.IHintObservable;
77 import org.simantics.utils.datastructures.hints.IHintTracker;
78 import org.simantics.utils.ui.LayoutUtils;
81 * @author Kalle Kondelin
83 public class SynchroniseView extends ViewPart {
85 public SynchroniseView() {
88 public class SessionContextProjectTracker extends HintTracker {
89 public SessionContextProjectTracker() {
90 IHintListener activeProjectListener = new HintListenerAdapter() {
92 public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
93 applySessionContext(getSessionContext());
96 addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener);
100 protected LocalResourceManager resourceManager;
102 protected Composite parent;
104 protected TreeViewer treeViewer;
106 private Map<String, String> args;
108 private ISessionContextProvider contextProvider;
110 private ISessionContext sessionContext;
112 protected IMemento memento;
114 private IHintTracker sessionContextTracker = new SessionContextProjectTracker();
116 private DisposeState disposeState = DisposeState.Alive;
118 protected ISessionContextChangedListener contextChangeListener = new ISessionContextChangedListener() {
120 public void sessionContextChanged(SessionContextChangedEvent event) {
121 sessionContext = event.getNewValue();
122 sessionContextTracker.track(sessionContext);
126 protected void setSessionContextTracker(IHintTracker tracker) {
127 this.sessionContextTracker = tracker;
130 protected Map<String, String> getViewArguments() {
134 protected DisposeState getDisposeState() {
138 public ISessionContext getSessionContext() {
139 return sessionContext;
142 public ISessionContextProvider getSessionContextProvider() {
143 return contextProvider;
147 public void createPartControl(Composite parent) {
148 this.parent = parent;
149 this.treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.FULL_SELECTION);
150 this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), treeViewer.getTree());
151 Images.getInstance(JFaceResources.getResources());
152 TreeColumnLayout ad = new TreeColumnLayout();
153 parent.setLayout(ad);
154 treeViewer.getTree().setHeaderVisible(true);
155 //treeViewer.getTree().setLinesVisible(true);
156 //treeViewer.setUseHashlookup(true);
157 //treeViewer.setAutoExpandLevel(3);
159 TreeViewerColumn nameColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
160 TreeViewerColumn typeColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
161 // TreeViewerColumn idColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
162 // TreeViewerColumn lookupIdColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
163 // TreeViewerColumn zColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
165 nameColumn.setLabelProvider(new MyColumnLabelProvider());
166 typeColumn.setLabelProvider(new MyColumnLabelProvider());
167 // idColumn.setLabelProvider(new MyColumnLabelProvider());
168 // lookupIdColumn.setLabelProvider(new MyColumnLabelProvider());
169 // zColumn.setLabelProvider(new MyColumnLabelProvider());
171 nameColumn.getColumn().setText("Name");
172 nameColumn.getColumn().setWidth(20);
173 ad.setColumnData(nameColumn.getColumn(), new ColumnWeightData(80, 100));
174 typeColumn.getColumn().setText("Type");
175 typeColumn.getColumn().setWidth(20);
176 ad.setColumnData(typeColumn.getColumn(), new ColumnWeightData(20, 120));
177 // idColumn.getColumn().setText("ID");
178 // idColumn.getColumn().setWidth(20);
179 // ad.setColumnData(idColumn.getColumn(), new ColumnWeightData(10, 50));
180 // lookupIdColumn.getColumn().setText("Lookup ID");
181 // lookupIdColumn.getColumn().setWidth(20);
182 // ad.setColumnData(lookupIdColumn.getColumn(), new ColumnWeightData(50, 100));
183 // zColumn.getColumn().setText("Z");
184 // zColumn.getColumn().setWidth(70);
185 // ad.setColumnData(zColumn.getColumn(), new ColumnWeightData(10, 70));
187 createControls(parent);
193 * Invoked when this viewpart is disposed. Unhooks the view from its
194 * ISessionContextProvider. Overriding is allowed but super.dispose() must
197 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
200 public void dispose() {
201 disposeState = DisposeState.Disposing;
203 if (contextProvider != null) {
204 contextProvider.removeContextChangedListener(contextChangeListener);
205 contextProvider = null;
207 sessionContextTracker.untrack();
208 resourceManager.dispose();
209 resourceManager = null;
211 sessionContext = null;
215 disposeState = DisposeState.Disposed;
220 public void setFocus() {
225 public void init(IViewSite site) throws PartInitException {
227 this.args = ViewArgumentUtils.parseViewArguments(this);
231 public void init(IViewSite site, IMemento memento) throws PartInitException {
232 super.init(site, memento);
233 this.args = ViewArgumentUtils.parseViewArguments(this);
234 this.memento = memento;
238 public void saveState(IMemento memento) {
239 if (this.memento != null) {
240 memento.putMemento(this.memento);
242 // if (explorer != null)
243 // explorer.saveState(memento);
246 protected final void attachToSession() {
247 // Track active ISessionContext changes
248 contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow());
249 contextProvider.addContextChangedListener(contextChangeListener);
251 // Perform first-time initialization of the explorer and its input.
252 applySessionContext(contextProvider.getSessionContext());
255 // private abstract class NameAndDescriptionToolTip extends ToolTip {
256 // public NameAndDescriptionToolTip(Control control, int style) {
257 // super(control, style, false);
260 // protected abstract Object getModelElement(Event event);
263 // * Adds logic to only show a tooltip if a meaningful item is under the
266 // protected boolean shouldCreateToolTip(Event event) {
267 // if (!super.shouldCreateToolTip(event))
269 // Object tableElement = getModelElement(event);
270 // return tableElement != null && tableElement instanceof DisplayElement;
273 // protected Composite createToolTipContentArea(Event event,
274 // Composite parent) {
275 // Object modelElement = getModelElement(event);
277 // Image iconImage = null;
278 // String nameString = "no name";
280 // if (modelElement instanceof DisplayElement) {
282 // nameString = "name";
285 // // Create the content area
286 // Composite composite = new Composite(parent, SWT.NONE);
287 // composite.setBackground(parent.getDisplay().getSystemColor(
288 // SWT.COLOR_INFO_BACKGROUND));
289 // composite.setLayout(new GridLayout(2, false));
291 // // The title area with the icon (if there is one) and label.
292 // Label title = createEntry(composite, iconImage, nameString);
293 //// title.setFont(tooltipHeading);
294 // GridDataFactory.createFrom((GridData)title.getLayoutData())
295 // .hint(SWT.DEFAULT, SWT.DEFAULT)
296 //// .minSize(MIN_TOOLTIP_WIDTH, 1)
299 // // The description (if there is one)
300 //// String descriptionString = "description";
301 //// if (descriptionString != null)
302 //// createEntry(composite, null, descriptionString);
304 // // Other Content to add
305 // addContent(composite, modelElement);
311 // * Adds a line of information to <code>parent</code>. If
312 // * <code>icon</code> is not <code>null</code>, an icon is placed on the
313 // * left, and then a label with <code>text</code>.
316 // * the composite to add the entry to
318 // * the icon to place next to the text. <code>null</code> for
321 // * the text to display
322 // * @return the created label
324 // protected Label createEntry(Composite parent, Image icon, String text) {
325 // if (icon != null) {
326 // Label iconLabel = new Label(parent, SWT.NONE);
327 // iconLabel.setImage(icon);
328 // iconLabel.setBackground(parent.getDisplay().getSystemColor(
329 // SWT.COLOR_INFO_BACKGROUND));
330 // iconLabel.setData(new GridData());
333 // Label textLabel = new Label(parent, SWT.WRAP);
335 // if(icon == null) {
336 // GridDataFactory.generate(textLabel, 2, 1);
338 // GridDataFactory.generate(textLabel, 1, 1);
341 // textLabel.setText(text);
342 // textLabel.setBackground(parent.getDisplay().getSystemColor(
343 // SWT.COLOR_INFO_BACKGROUND));
348 // * Adds a line of information to <code>parent</code>. If
349 // * <code>icon</code> is not <code>null</code>, an icon is placed on the
350 // * left, and then a label with <code>text</code>, which supports using
351 // * anchor tags to creates links
354 // * the composite to add the entry to
356 // * the icon to place next to the text. <code>null</code> for
359 // * the text to display
360 // * @return the created link
362 // protected Text createEntryWithText(Composite parent, Image icon, String text) {
363 // if (icon != null) {
364 // Label iconLabel = new Label(parent, SWT.NONE);
365 // iconLabel.setImage(icon);
366 // iconLabel.setBackground(parent.getDisplay().getSystemColor(
367 // SWT.COLOR_INFO_BACKGROUND));
368 // iconLabel.setData(new GridData());
370 // Text texts = new Text(parent, SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL);
371 // if(icon == null) {
372 // GridDataFactory.generate(texts, 2, 1);
374 // texts.setText(text);
375 // texts.setBackground(parent.getDisplay().getSystemColor(
376 // SWT.COLOR_INFO_BACKGROUND));
380 // protected void addContent(Composite destination, Object modelElement) {
384 private class ItemDetailToolTip extends NameAndDescriptionToolTip {
385 private final boolean DEBUG = false;
386 private TreeViewer viewer;
388 private ItemDetailToolTip(TreeViewer viewer, Tree tree, ViewerFilter filter) {
389 super(tree,NO_RECREATE);
391 this.viewer = viewer;
392 this.setHideOnMouseDown(false);
394 public Point getLocation(Point tipSize, Event event) {
395 // try to position the tooltip at the bottom of the cell
396 ViewerCell cell = viewer.getCell(new Point(event.x, event.y));
398 return tree.toDisplay(event.x,cell.getBounds().y+cell.getBounds().height);
399 return super.getLocation(tipSize, event);
401 protected Object getToolTipArea(Event event) {
402 // Ensure that the tooltip is hidden when the cell is left
403 return viewer.getCell(new Point(event.x, event.y));
405 protected void addContent(Composite destination, Object modelElement) {
406 final DisplayElement item = (DisplayElement)modelElement;
408 System.out.println("add content");
411 text = modelElement.toString();
412 createEntryWithText(destination, null, text.toString());
415 protected Object getModelElement(Event event) {
416 org.eclipse.swt.widgets.TreeItem treeItem = tree.getItem(new Point(event.x, event.y));
417 if (treeItem == null)
419 return treeItem.getData();
422 class MyColumnLabelProvider extends ColumnLabelProvider {
424 public void update(ViewerCell cell) {
425 //NodeProxy proxy = (NodeProxy) cell.getElement();
426 cell.setText("Kraa");
427 cell.setImage(Images.getInstance().OTHER_IMAGE);
430 protected void createControls(final Composite parent) {
431 parent.setLayout(LayoutUtils.createNoBorderGridLayout(1, false));
432 GridDataFactory.fillDefaults().grab(true, true).applyTo(treeViewer.getTree());
433 treeViewer.setContentProvider(new UndoContentProvider(Simantics.getSession()));
434 treeViewer.setLabelProvider(new LabelProvider() {
436 public Image getImage(Object element) {
437 if (element instanceof ChangeSetElement)
438 return Images.getInstance().CHANGE_SET_IMAGE;
439 else if (element instanceof DisplayElement)
440 return Images.getInstance().DISPLAY_IMAGE;
441 else if (element instanceof ResourceElement)
442 return Images.getInstance().RESOURCE_IMAGE;
443 else if (element instanceof StringElement)
444 return Images.getInstance().STRING_IMAGE;
445 else if (element instanceof UndoCombinedElement)
446 return Images.getInstance().COMBINED_IMAGE;
447 else if (element instanceof RedoContextElement)
448 return Images.getInstance().REDO_IMAGE;
449 else if (element instanceof UndoContextElement)
450 return Images.getInstance().UNDO_IMAGE;
452 return Images.getInstance().OTHER_IMAGE;
455 public String getText(Object element) {
456 return element.toString();
459 //viewer.setSorter(new ViewerSorter());
460 treeViewer.setInput(this);
461 Control control = treeViewer.getControl();
462 // ISelectionProvider selectionProvider = new ISelectionProvider() {
464 // public void addSelectionChangedListener(ISelectionChangedListener listener) {
467 // public ISelection getSelection() {
471 // public void removeSelectionChangedListener(ISelectionChangedListener listener) {
474 // public void setSelection(ISelection selection) {
477 createContextMenu(control, getSite());
479 // ImageDescriptor desc = BundleUtils.getImageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_undo.png");
480 // getViewSite().getActionBars().getToolBarManager().add(new Action("GetUndoHistory", desc) {
482 // public void run() {
483 // treeViewer.setContentProvider(new UndoContentProvider(Simantics.getSession()));
486 // getViewSite().getActionBars().getToolBarManager().add(new Action("DumpSelectedRevision", Activator.BIN_CLOSED_ICON) {
488 // public void run() {
489 // IStructuredSelection is = (IStructuredSelection)viewer.getSelection();
490 // Object o = is.getFirstElement();
491 // if (o instanceof ChangeSetElement) {
492 // ChangeSetElement ce = (ChangeSetElement)o;
493 // long csid = ce.getChangeSetIdentifier().getId();
494 // ManagementSupport ms = Simantics.getSession().getService(ManagementSupport.class);
496 // ms.dumpRevision(csid);
497 // ShowMessage.showInformation("DumpSelectedRevision", "Operation was successful.");
498 // } catch (DatabaseException e) {
499 // ExceptionUtils.logAndShowError(e);
505 public IMenuManager createContextMenu(Control control, IWorkbenchSite site) {
506 final MenuManager mm = new MenuManager("#TeamViewPopup", "#TeamViewPopup");
507 mm.setRemoveAllWhenShown(true);
508 mm.addMenuListener(new IMenuListener() {
510 public void menuAboutToShow(IMenuManager manager) {
511 mm.add(new GroupMarker(IWorkbenchActionConstants.WB_START));
514 Menu menu = mm.createContextMenu(control);
515 control.setMenu(menu);
517 if (site instanceof IWorkbenchPartSite) {
518 ((IWorkbenchPartSite) site).registerContextMenu(mm.getId(), mm, site.getSelectionProvider());
519 } else if (site instanceof IPageSite) {
520 ((IPageSite) site).registerContextMenu(mm.getId(), mm, site.getSelectionProvider());
529 protected GraphExplorer createExplorerControl(Composite parent) {
530 return GraphExplorerFactory.getInstance().selectionDataResolver(new DefaultSelectionDataResolver()).create(parent);
533 // Needed for preventing unnecessary re-initialization of the explorer with the same input.
534 // private Object currentInput;
537 * Invoke this to reinitialize the explorer and reset its input. The input
538 * will be resolved from the specified ISessionContext based on the
539 * {@link SessionContextInputSource} that is currently in use. If the input
540 * is identical to the previous input, nothing will be done.
544 protected final boolean applySessionContext(ISessionContext context) {
545 // If control is not alive anymore, do nothing.
546 if (disposeState != DisposeState.Alive)
549 this.sessionContext = context;
551 // Start tracking the session context.
552 // This will cause IHintListeners of the sessionContextTracker to fire.
553 // For this we need the above input equality (identity) checking.
554 sessionContextTracker.track(sessionContext);
559 class IncomingContentProvider implements ITreeContentProvider {
560 class IncomingElement extends ChangeSetElement {
561 IncomingElement(Session session, ChangeSetIdentifier cs) {
565 IncomingElement[] changeSetIds;
566 IncomingContentProvider(Session session, Shell parent) {
567 //this.session = session;
568 // PublishSynchroniseSupport ps = session.getService(PublishSynchroniseSupport.class);
570 Collection<ChangeSetIdentifier> cids = new ArrayList<ChangeSetIdentifier>();
572 changeSetIds = new IncomingElement[0];
574 changeSetIds = new IncomingElement[cids.size()];
575 Iterator<ChangeSetIdentifier> it = cids.iterator();
577 while (it.hasNext()) {
578 changeSetIds[i++] = new IncomingElement(session, it.next());
580 assert(i == cids.size());
582 // } catch (DatabaseException e) {
583 // changeSetIds = new IncomingElement[0];
584 // ExceptionUtils.logAndShowError(e);
589 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
593 public void dispose() {
597 public Object[] getElements(Object inputElement) {
602 public boolean hasChildren(Object element) {
603 return changeSetIds.length > 0;
607 public Object getParent(Object element) {
612 public Object[] getChildren(Object parentElement) {
617 class OutgoingContentProvider implements ITreeContentProvider {
618 class OutgoingElement extends ChangeSetElement {
619 OutgoingElement(Session session, ChangeSetIdentifier cs) {
623 OutgoingElement[] changeSetIds;
624 OutgoingContentProvider(Session session) {
625 // PublishSynchroniseSupport ps = session.getService(PublishSynchroniseSupport.class);
627 Collection<ChangeSetIdentifier> cids = new ArrayList<ChangeSetIdentifier>();
629 changeSetIds = new OutgoingElement[0];
631 changeSetIds = new OutgoingElement[cids.size()];
632 Iterator<ChangeSetIdentifier> it = cids.iterator();
634 while (it.hasNext()) {
635 changeSetIds[i++] = new OutgoingElement(session, it.next());
637 assert(i == cids.size());
639 // } catch (DatabaseException e) {
640 // ExceptionUtils.logAndShowError(e);
641 // changeSetIds = new OutgoingElement[0];
646 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
650 public void dispose() {
654 public Object[] getElements(Object inputElement) {
659 public boolean hasChildren(Object element) {
660 if (element instanceof TreeElement)
661 return ((TreeElement)element).hasChildren();
666 public Object getParent(Object element) {
671 public Object[] getChildren(Object parentElement) {
672 if (parentElement instanceof TreeElement)
673 return ((TreeElement)parentElement).getChildren();
681 class ResourceElement extends TreeElement {
682 private Session session;
683 private String resourceUri;
684 private String resourceName;
685 private Resource resource;
686 ResourceElement(Session session, String resource) {
687 this.session = session;
688 this.resourceUri = resource;
690 ResourceElement(Session session, Resource resource) {
691 this.session = session;
692 this.resource = resource;
695 protected Image getIdImage() {
696 return Images.getInstance().RESOURCE_IMAGE;
699 protected String getIdText() {
700 String s = resource.toString();
701 return s.substring(0, Math.min(10, s.length()));
703 private String getNameByUri() {
705 String t = session.syncRequest(new Read<String>() {
707 public String perform(ReadGraph g) throws DatabaseException {
708 resource = g.getResource(resourceUri);
709 Layer0 l0 = Layer0.getInstance(g);
710 resourceName = g.getPossibleRelatedValue(resource, l0.HasName, Bindings.STRING);
711 if (null == resourceName) {
712 Set<Resource> types = g.getTypes(resource);
713 if (types.size() > 0) {
714 Iterator<Resource> i = types.iterator();
715 Resource r = i.next();
716 resourceName = g.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING);
719 if (null == resourceName)
720 resourceName = resourceUri;
725 } catch (DatabaseException e) {
729 private String getName() {
731 String t = session.syncRequest(new Read<String>() {
733 public String perform(ReadGraph g) throws DatabaseException {
734 Layer0 l0 = Layer0.getInstance(g);
735 resourceName = g.getPossibleRelatedValue(resource, l0.HasName, Bindings.STRING);
736 if (null == resourceName) {
737 Set<Resource> types = g.getTypes(resource);
738 if (types.size() > 0) {
739 Iterator<Resource> i = types.iterator();
740 Resource r = i.next();
741 resourceName = g.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING);
744 if (null == resourceName)
745 resourceName = resourceUri;
750 } catch (DatabaseException e) {
754 private Resource getParent() {
756 Resource parent = session.syncRequest(new Read<Resource>() {
758 public Resource perform(ReadGraph g) throws DatabaseException {
759 Layer0 l0 = Layer0.getInstance(g);
760 return g.getPossibleObject(resource, l0.PartOf);
765 } catch (DatabaseException e) {
769 public String toString() {
770 if (null == resourceName && null != resourceUri)
771 return getNameByUri();
772 else if (null != resource && null == resourceUri)
777 boolean hasChildren() {
778 Resource p = getParent();
785 Object[] getChildren() {
786 Resource p = getParent();
788 return new Object[0];
789 Object[] objects = new Object[1];
790 objects[0] = new ResourceElement(session, p);