You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ph...@apache.org on 2016/03/10 05:29:11 UTC
svn commit: r1734347 - in
/zookeeper/branches/branch-3.5/src/contrib/zooinspector: ./
src/java/org/apache/zookeeper/inspector/gui/
src/java/org/apache/zookeeper/inspector/gui/actions/
src/java/org/apache/zookeeper/inspector/manager/
Author: phunt
Date: Thu Mar 10 04:29:10 2016
New Revision: 1734347
URL: http://svn.apache.org/viewvc?rev=1734347&view=rev
Log:
ZOOKEEPER-2087 Few UX improvements in ZooInspector (Adam Dudczak via phunt)
Added:
zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/
zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/AddNodeAction.java
zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/DeleteNodeAction.java
zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/NodesCache.java
Modified:
zookeeper/branches/branch-3.5/src/contrib/zooinspector/ivy.xml
zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java
zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/ZooInspectorManagerImpl.java
Modified: zookeeper/branches/branch-3.5/src/contrib/zooinspector/ivy.xml
URL: http://svn.apache.org/viewvc/zookeeper/branches/branch-3.5/src/contrib/zooinspector/ivy.xml?rev=1734347&r1=1734346&r2=1734347&view=diff
==============================================================================
--- zookeeper/branches/branch-3.5/src/contrib/zooinspector/ivy.xml (original)
+++ zookeeper/branches/branch-3.5/src/contrib/zooinspector/ivy.xml Thu Mar 10 04:29:10 2016
@@ -32,6 +32,8 @@
</configurations>
<dependencies>
+ <dependency org="com.google.guava" name="guava" rev="18.0" />
+
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5"/>
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" transitive="false" conf="test->default" />
Modified: zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
URL: http://svn.apache.org/viewvc/zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java?rev=1734347&r1=1734346&r2=1734347&view=diff
==============================================================================
--- zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java (original)
+++ zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java Thu Mar 10 04:29:10 2016
@@ -34,6 +34,8 @@ import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.SwingWorker;
+import org.apache.zookeeper.inspector.gui.actions.AddNodeAction;
+import org.apache.zookeeper.inspector.gui.actions.DeleteNodeAction;
import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer;
import org.apache.zookeeper.inspector.logger.LoggerFactory;
import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
@@ -102,74 +104,12 @@ public class ZooInspectorPanel extends J
treeViewer.refreshView();
}
});
- toolbar.addActionListener(Toolbar.Button.addNode, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- final List<String> selectedNodes = treeViewer
- .getSelectedNodes();
- if (selectedNodes.size() == 1) {
- final String nodeName = JOptionPane.showInputDialog(
- ZooInspectorPanel.this,
- "Please Enter a name for the new node",
- "Create Node", JOptionPane.INFORMATION_MESSAGE);
- if (nodeName != null && nodeName.length() > 0) {
- SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
-
- @Override
- protected Boolean doInBackground() throws Exception {
- return ZooInspectorPanel.this.zooInspectorManager
- .createNode(selectedNodes.get(0),
- nodeName);
- }
-
- @Override
- protected void done() {
- treeViewer.refreshView();
- }
- };
- worker.execute();
- }
- } else {
- JOptionPane.showMessageDialog(ZooInspectorPanel.this,
- "Please select 1 parent node for the new node.");
- }
- }
- });
- toolbar.addActionListener(Toolbar.Button.deleteNode, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- final List<String> selectedNodes = treeViewer
- .getSelectedNodes();
- if (selectedNodes.size() == 0) {
- JOptionPane.showMessageDialog(ZooInspectorPanel.this,
- "Please select at least 1 node to be deleted");
- } else {
- int answer = JOptionPane.showConfirmDialog(
- ZooInspectorPanel.this,
- "Are you sure you want to delete the selected nodes?"
- + "(This action cannot be reverted)",
- "Confirm Delete", JOptionPane.YES_NO_OPTION,
- JOptionPane.WARNING_MESSAGE);
- if (answer == JOptionPane.YES_OPTION) {
- SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
-
- @Override
- protected Boolean doInBackground() throws Exception {
- for (String nodePath : selectedNodes) {
- ZooInspectorPanel.this.zooInspectorManager
- .deleteNode(nodePath);
- }
- return true;
- }
-
- @Override
- protected void done() {
- treeViewer.refreshView();
- }
- };
- worker.execute();
- }
- }
- }
- });
+
+ toolbar.addActionListener(Toolbar.Button.addNode,
+ new AddNodeAction(this, treeViewer, zooInspectorManager));
+ toolbar.addActionListener(Toolbar.Button.deleteNode,
+ new DeleteNodeAction(this, treeViewer, zooInspectorManager));
+
toolbar.addActionListener(Toolbar.Button.nodeViewers, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Modified: zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java
URL: http://svn.apache.org/viewvc/zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java?rev=1734347&r1=1734346&r2=1734347&view=diff
==============================================================================
--- zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java (original)
+++ zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java Thu Mar 10 04:29:10 2016
@@ -21,6 +21,8 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
@@ -35,6 +37,7 @@ import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
+import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.event.TreeSelectionListener;
@@ -44,10 +47,13 @@ import javax.swing.tree.DefaultTreeModel
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
+import org.apache.zookeeper.inspector.gui.actions.AddNodeAction;
+import org.apache.zookeeper.inspector.gui.actions.DeleteNodeAction;
import org.apache.zookeeper.inspector.manager.NodeListener;
import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
import com.nitido.utils.toaster.Toaster;
+import static javax.swing.KeyStroke.getKeyStroke;
/**
* A {@link JPanel} for showing the tree view of all the nodes in the zookeeper
@@ -69,9 +75,29 @@ public class ZooInspectorTreeViewer exte
public ZooInspectorTreeViewer(
final ZooInspectorManager zooInspectorManager,
TreeSelectionListener listener, IconResource iconResource) {
+
+ this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
+ .put(getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK), "deleteNode");
+
+ this.getActionMap().put("deleteNode",
+ new DeleteNodeAction(this, this, zooInspectorManager));
+
+ this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
+ .put(getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK), "addNode");
+
+ this.getActionMap().put("addNode",
+ new AddNodeAction(this, this, zooInspectorManager));
+
this.zooInspectorManager = zooInspectorManager;
this.setLayout(new BorderLayout());
final JPopupMenu popupMenu = new JPopupMenu();
+
+ final JMenuItem addNode = new JMenuItem("Add Node");
+ addNode.addActionListener(new AddNodeAction(this, this, zooInspectorManager));
+
+ final JMenuItem deleteNode = new JMenuItem("Delete Node");
+ deleteNode.addActionListener(new DeleteNodeAction(this, this, zooInspectorManager));
+
final JMenuItem addNotify = new JMenuItem("Add Change Notification");
this.toasterManager = new Toaster();
this.toasterManager.setBorderColor(Color.BLACK);
@@ -105,6 +131,8 @@ public class ZooInspectorTreeViewer exte
// watched, and only show remove if a selected node is being
// watched
popupMenu.removeAll();
+ popupMenu.add(addNode);
+ popupMenu.add(deleteNode);
popupMenu.add(addNotify);
popupMenu.add(removeNotify);
popupMenu.show(ZooInspectorTreeViewer.this, e.getX(), e
Added: zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/AddNodeAction.java
URL: http://svn.apache.org/viewvc/zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/AddNodeAction.java?rev=1734347&view=auto
==============================================================================
--- zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/AddNodeAction.java (added)
+++ zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/AddNodeAction.java Thu Mar 10 04:29:10 2016
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui.actions;
+
+import org.apache.zookeeper.inspector.gui.ZooInspectorPanel;
+import org.apache.zookeeper.inspector.gui.ZooInspectorTreeViewer;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import java.awt.event.KeyEvent;
+
+public class AddNodeAction extends AbstractAction {
+
+ private JPanel panel;
+ private ZooInspectorTreeViewer treeViewer;
+ private ZooInspectorManager zooInspectorManager;
+
+ public AddNodeAction(JPanel parentPanel,
+ ZooInspectorTreeViewer treeViewer,
+ ZooInspectorManager zooInspectorManager) {
+ this.panel = parentPanel;
+ this.treeViewer = treeViewer;
+ this.zooInspectorManager = zooInspectorManager;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ final List<String> selectedNodes = treeViewer
+ .getSelectedNodes();
+ if (selectedNodes.size() == 1) {
+ final String nodeName = JOptionPane.showInputDialog(
+ panel,
+ "Please Enter a name for the new node",
+ "Create Node", JOptionPane.INFORMATION_MESSAGE);
+ if (nodeName != null && nodeName.length() > 0) {
+ SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+ @Override
+ protected Boolean doInBackground() throws Exception {
+ return zooInspectorManager
+ .createNode(selectedNodes.get(0),
+ nodeName);
+ }
+
+ @Override
+ protected void done() {
+ treeViewer.refreshView();
+ }
+ };
+ worker.execute();
+ }
+ } else {
+ JOptionPane.showMessageDialog(panel,
+ "Please select 1 parent node for the new node.");
+ }
+ }
+}
Added: zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/DeleteNodeAction.java
URL: http://svn.apache.org/viewvc/zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/DeleteNodeAction.java?rev=1734347&view=auto
==============================================================================
--- zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/DeleteNodeAction.java (added)
+++ zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/gui/actions/DeleteNodeAction.java Thu Mar 10 04:29:10 2016
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui.actions;
+
+import org.apache.zookeeper.inspector.gui.ZooInspectorTreeViewer;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import java.awt.event.KeyEvent;
+
+public class DeleteNodeAction extends AbstractAction {
+
+ private JPanel parentPanel;
+ private ZooInspectorTreeViewer treeViewer;
+ private ZooInspectorManager zooInspectorManager;
+
+ public DeleteNodeAction(JPanel parentPanel,
+ ZooInspectorTreeViewer treeViewer,
+ ZooInspectorManager zooInspectorManager) {
+ this.parentPanel = parentPanel;
+ this.treeViewer = treeViewer;
+ this.zooInspectorManager = zooInspectorManager;
+ }
+
+
+ public void actionPerformed(ActionEvent e) {
+ final List<String> selectedNodes = treeViewer
+ .getSelectedNodes();
+ if (selectedNodes.size() == 0) {
+ JOptionPane.showMessageDialog(parentPanel,
+ "Please select at least 1 node to be deleted");
+ } else {
+ int answer = JOptionPane.showConfirmDialog(
+ parentPanel,
+ "Are you sure you want to delete the selected nodes?"
+ + "(This action cannot be reverted)",
+ "Confirm Delete", JOptionPane.YES_NO_OPTION,
+ JOptionPane.WARNING_MESSAGE
+ );
+ if (answer == JOptionPane.YES_OPTION) {
+ SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+ @Override
+ protected Boolean doInBackground() throws Exception {
+ for (String nodePath : selectedNodes) {
+ zooInspectorManager
+ .deleteNode(nodePath);
+ }
+ return true;
+ }
+
+ @Override
+ protected void done() {
+ treeViewer.refreshView();
+ }
+ };
+ worker.execute();
+ }
+ }
+ }
+}
Added: zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/NodesCache.java
URL: http://svn.apache.org/viewvc/zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/NodesCache.java?rev=1734347&view=auto
==============================================================================
--- zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/NodesCache.java (added)
+++ zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/NodesCache.java Thu Mar 10 04:29:10 2016
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.manager;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+public class NodesCache {
+
+ public static final int CACHE_SIZE = 40000;
+
+ public static final int EXPIRATION_TIME = 100;
+
+ private final LoadingCache<String, List<String>> nodes;
+
+ private ZooKeeper zooKeeper;
+
+ public NodesCache(ZooKeeper zooKeeper) {
+ this.zooKeeper = zooKeeper;
+ this.nodes = CacheBuilder.newBuilder()
+ .maximumSize(CACHE_SIZE)
+ .expireAfterWrite(EXPIRATION_TIME, TimeUnit.MILLISECONDS)
+ .build(
+ new CacheLoader<String, List<String>>() {
+ @Override
+ public List<String> load(String nodePath) throws Exception {
+ return getChildren(nodePath);
+ }
+ }
+ );
+ }
+
+ public List<String> getChildren(String nodePath) {
+ try {
+ Stat s = zooKeeper.exists(nodePath, false);
+ if (s != null) {
+ List<String> children = this.zooKeeper.getChildren(nodePath, false);
+ Collections.sort(children);
+ return children;
+ }
+ } catch (Exception e) {
+ LoggerFactory.getLogger().error(
+ "Error occurred retrieving child of node: " + nodePath, e
+ );
+ }
+ return null;
+ }
+
+ public String getNodeChild(String nodePath, int index) {
+ List<String> childNodes = null;
+ try {
+ childNodes = nodes.get(nodePath);
+ return childNodes.get(index);
+ } catch (ExecutionException e) {
+ LoggerFactory.getLogger().error(
+ "Error occurred retrieving child " + index + "of node: " + nodePath, e
+ );
+ }
+ return null;
+ }
+
+}
Modified: zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/ZooInspectorManagerImpl.java
URL: http://svn.apache.org/viewvc/zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/ZooInspectorManagerImpl.java?rev=1734347&r1=1734346&r2=1734347&view=diff
==============================================================================
--- zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/ZooInspectorManagerImpl.java (original)
+++ zookeeper/branches/branch-3.5/src/contrib/zooinspector/src/java/org/apache/zookeeper/inspector/manager/ZooInspectorManagerImpl.java Thu Mar 10 04:29:10 2016
@@ -109,6 +109,7 @@ public class ZooInspectorManagerImpl imp
private String defaultHosts;
private String defaultAuthScheme;
private String defaultAuthValue;
+ private NodesCache nodesCache;
/**
* @throws IOException
@@ -181,6 +182,8 @@ public class ZooInspectorManagerImpl imp
}
if (!connected){
disconnect();
+ } else {
+ this.nodesCache = new NodesCache(zooKeeper);
}
return connected;
}
@@ -216,14 +219,7 @@ public class ZooInspectorManagerImpl imp
*/
public List<String> getChildren(String nodePath) {
if (connected) {
- try {
-
- return zooKeeper.getChildren(nodePath, false);
- } catch (Exception e) {
- LoggerFactory.getLogger().error(
- "Error occurred retrieving children of node: "
- + nodePath, e);
- }
+ return nodesCache.getChildren(nodePath);
}
return null;
@@ -263,17 +259,7 @@ public class ZooInspectorManagerImpl imp
*/
public String getNodeChild(String nodePath, int childIndex) {
if (connected) {
- try {
- Stat s = zooKeeper.exists(nodePath, false);
- if (s != null) {
- return this.zooKeeper.getChildren(nodePath, false).get(
- childIndex);
- }
- } catch (Exception e) {
- LoggerFactory.getLogger().error(
- "Error occurred retrieving child " + childIndex
- + " of node: " + nodePath, e);
- }
+ return this.nodesCache.getNodeChild(nodePath, childIndex);
}
return null;
}
@@ -296,7 +282,7 @@ public class ZooInspectorManagerImpl imp
String parentPath = nodePath.substring(0, index);
String child = nodePath.substring(index + 1);
if (parentPath != null && parentPath.length() > 0) {
- List<String> children = this.getChildren(parentPath);
+ List<String> children = this.nodesCache.getChildren(parentPath);
if (children != null) {
return children.indexOf(child);
}
@@ -860,7 +846,11 @@ public class ZooInspectorManagerImpl imp
}
public List<String> getDefaultNodeViewerConfiguration() throws IOException {
- return loadNodeViewersFile(defaultNodeViewersFile);
+ List<String> defaultNodeViewers = loadNodeViewersFile(defaultNodeViewersFile);
+ if (defaultNodeViewers.isEmpty()) {
+ LoggerFactory.getLogger().warn("List of default node viewers is empty");
+ }
+ return defaultNodeViewers;
}
/*