Author: rob.stryker(a)jboss.com
Date: 2011-02-24 00:18:05 -0500 (Thu, 24 Feb 2011)
New Revision: 29301
Added:
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.ui/src/org/jboss/tools/internal/deltacloud/ui/utils/WorkbenchUtils.java
Modified:
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/META-INF/MANIFEST.MF
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/src/org/jboss/tools/deltacloud/integration/rse/util/RSEUtils.java
Log:
JBIDE-8372 to maintenance branch
Modified:
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/META-INF/MANIFEST.MF
===================================================================
---
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/META-INF/MANIFEST.MF 2011-02-24
04:29:10 UTC (rev 29300)
+++
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/META-INF/MANIFEST.MF 2011-02-24
05:18:05 UTC (rev 29301)
@@ -26,8 +26,9 @@
org.jboss.tools.deltacloud.core,
org.jboss.tools.deltacloud.ui,
org.jboss.ide.eclipse.as.core,
- org.eclipse.core.resources;bundle-version="[3.6.0,4.0.0)",
- org.jboss.ide.eclipse.as.rse.core;bundle-version="[0.9.0,2.0.0)",
- org.eclipse.wst.server.core;bundle-version="[1.1.204,2.0.0)",
- org.eclipse.wst.server.ui;bundle-version="[1.1.205,2.0.0)",
- org.eclipse.jsch.core;bundle-version="1.1.200"
+ org.eclipse.core.resources,
+ org.jboss.ide.eclipse.as.rse.core,
+ org.eclipse.wst.server.core,
+ org.eclipse.wst.server.ui,
+ org.eclipse.jsch.core
+Import-Package: com.jcraft.jsch
Modified:
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/src/org/jboss/tools/deltacloud/integration/rse/util/RSEUtils.java
===================================================================
---
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/src/org/jboss/tools/deltacloud/integration/rse/util/RSEUtils.java 2011-02-24
04:29:10 UTC (rev 29300)
+++
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.integration/src/org/jboss/tools/deltacloud/integration/rse/util/RSEUtils.java 2011-02-24
05:18:05 UTC (rev 29301)
@@ -29,20 +29,25 @@
import org.eclipse.rse.core.model.ISystemRegistry;
import org.eclipse.rse.core.model.SystemStartHere;
import org.eclipse.rse.core.subsystems.IConnectorService;
+import org.eclipse.rse.core.subsystems.ISubSystem;
+import org.eclipse.rse.services.clientserver.messages.SystemOperationFailedException;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PartInitException;
import org.jboss.tools.deltacloud.core.DeltaCloudInstance;
import org.jboss.tools.deltacloud.integration.DeltaCloudIntegrationPlugin;
import org.jboss.tools.deltacloud.integration.Messages;
-import org.jboss.tools.deltacloud.integration.wizard.CreateServerFromRSEJob;
-import org.jboss.tools.internal.deltacloud.ui.utils.UIUtils;
+import org.jboss.tools.internal.deltacloud.ui.utils.WorkbenchUtils;
+import com.jcraft.jsch.JSchException;
+
/**
* @author André Dietisheim
+ * @author Rob Stryker
*/
public class RSEUtils {
+ private static final int RECONNECT_WAIT = 5000;
private static final String VIEW_REMOTESYSEXPLORER_ID =
"org.eclipse.rse.ui.view.systemView";
public static IRSESystemType getSSHOnlySystemType() {
@@ -68,26 +73,43 @@
return instance.getAlias();
}
+ @Deprecated
public static String createHostName(DeltaCloudInstance instance) {
- Assert.isLegal(instance != null, "Cannot get hostname: instance is not
defined");
-
- String hostName = instance.getHostName();
- Assert.isTrue(hostName != null && hostName.length() > 0,
- MessageFormat.format("Cannot get host name: not defined for instance {0}",
instance.getName()));
- return hostName;
+ return createRSEHostName(instance);
}
+
+ /**
+ * Returns the RSE host name for the given instance. Returns
+ * <code>null</code> if the instance is <code>null</null>.
+ *
+ * @param instance
+ * the instance to use to determine the host name for RSE
+ * @return the hostname
+ */
+ public static String createRSEHostName(DeltaCloudInstance instance) {
+ if (instance == null) {
+ return null;
+ }
+ return instance.getHostName();
+ }
+ @Deprecated
public static IHost createHost(String connectionName, String hostname, IRSESystemType
systemType,
ISystemRegistry systemRegistry) throws Exception {
+ return createHost("jboss", connectionName, hostname, systemType,
systemRegistry);
+ }
+
+ public static IHost createHost(String username, String connectionName, String hostname,
IRSESystemType systemType,
+ ISystemRegistry systemRegistry) throws Exception {
// TODO: Internationalize strings
Assert.isLegal(connectionName != null && connectionName.length() > 0,
"Cannot create Host: connectionName is not defined");
Assert.isLegal(hostname != null && hostname.length() > 0, "Cannot
create Host: hostname is not defined");
- Assert.isLegal(systemType != null, "Cannot create Host: system type is not
defined");
- Assert.isLegal(systemRegistry != null, "Cannot create Host: system registry is not
defined");
+ Assert.isNotNull(systemType, "Cannot create Host: system type is not
defined");
+ Assert.isNotNull(systemRegistry, "Cannot create Host: system registry is not
defined");
IHost host = systemRegistry.createHost(systemType, connectionName, hostname, null);
- host.setDefaultUserId("jboss"); //$NON-NLS-1$
+ host.setDefaultUserId(username); //$NON-NLS-1$
return host;
}
@@ -99,45 +121,106 @@
return services[0];
}
- public static void verifySystemConnected(IRemoteFileSubSystem system) {
- CreateServerFromRSEJob.verifySystemConnected(system);
- }
-
public static IStatus connect(IConnectorService service, IProgressMonitor monitor)
throws Exception {
- monitor.worked(1);
+ monitor.setTaskName(MessageFormat.format("Connecting to {0}...",
getHostName(service)));
service.connect(monitor);
- monitor.done();
+ monitor.setTaskName(MessageFormat.format("Connected to {0}.",
getHostName(service)));
return Status.OK_STATUS;
}
-
- public static IStatus connect(IConnectorService service, int timeout, IProgressMonitor
monitor) {
- monitor.beginTask("Connecting to remote server", timeout);
- monitor.setTaskName("Connecting to remote server");
- IStatus status = null;
- int count = 0;
- while( status == null && count < timeout && !monitor.isCanceled())
{
+
+ public static IStatus connect(IRemoteFileSubSystem service, IProgressMonitor monitor)
throws Exception {
+ Assert.isNotNull(service, "No service defined to connect to");
+
+ String hostName = getHostName(service);
+ monitor.setTaskName(MessageFormat.format("Connecting to {0}...", hostName));
+ service.connect(monitor, false);
+ monitor.setTaskName(MessageFormat.format("Connected to server {0}.",
hostName));
+ return Status.OK_STATUS;
+ }
+
+ public static String getHostName(IRemoteFileSubSystem service) {
+ String hostName = "";
+ if (service.getHost() != null) {
+ hostName = service.getHost().getName();
+ }
+ return hostName;
+ }
+
+ public static String getHostName(IConnectorService service) {
+ String hostName = "";
+ if (service.getHost() != null) {
+ hostName = service.getHost().getName();
+ }
+ return hostName;
+ }
+
+ /**
+ * Tries to connects to the given service for the given time. Progress will
+ * be reported on the given monitor.
+ *
+ * @param service
+ * the service to connect to
+ * @param timeout
+ * the timeout to apply
+ * @param monitor
+ * the monitor
+ * @return the restult of the connection attempt
+ * @throws Exception
+ */
+ public static IStatus connect(IConnectorService service, long timeout, IProgressMonitor
monitor) throws Exception {
+ long start = System.currentTimeMillis();
+ double scale = (double) 100 / timeout;
+ long current = start;
+ long last = start;
+ monitor.beginTask(MessageFormat.format("Connecting to {0}...",
getHostName(service)), 100);
+ while (!monitor.isCanceled()) {
+ current = System.currentTimeMillis();
try {
- status = connect(service, monitor);
+ return connect(service, monitor);
+ } catch (OperationCanceledException oce) {
monitor.done();
- return status;
- } catch(OperationCanceledException oce) {
- monitor.done();
return Status.CANCEL_STATUS;
- } catch(Exception e) {
- count += 1000;
- monitor.worked(1000);
- try {
- Thread.sleep(1000);
- } catch(InterruptedException ie) {
+ } catch (Exception e) {
+ if (didUserNotAcceptKey(e)) {
+ return Status.CANCEL_STATUS;
}
+
+ monitor.setTaskName(
+ MessageFormat.format("Could not connect to {0}. Trying again...",
getHostName(service)));
+ monitor.worked(getProgress(current, last, scale));
+ last = current;
+ if (current < start + timeout) {
+ try {
+ Thread.sleep(RECONNECT_WAIT);
+ } catch (InterruptedException ie) {
+ break;
+ }
+ } else {
+ monitor.done();
+ throw e;
+ }
}
}
- monitor.done();
- return status;
+ return Status.CANCEL_STATUS;
}
-
-
- public static Job connect(String connectionName, final IConnectorService service)
+
+ private static boolean didUserNotAcceptKey(Exception e) {
+ if (e instanceof SystemOperationFailedException) {
+ Throwable t = ((SystemOperationFailedException) e).getRemoteException();
+ if (t instanceof JSchException) {
+ return t.getMessage() != null
+ && t.getMessage().contains("reject HostKey:");
+ }
+ }
+ return false;
+ }
+
+ private static int getProgress(long current, long last, double scale) {
+ double progress = (current - last) * scale;
+ return (int) Math.ceil(progress);
+ }
+
+ public static Job connect(final String connectionName, final IConnectorService service)
throws Exception {
// TODO: internationalize strings
Assert.isLegal(connectionName != null,
@@ -148,10 +231,16 @@
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
- return connect(service, monitor);
- } catch(Exception e) {
+ monitor.beginTask(NLS.bind(Messages.RSE_CONNECTING_MESSAGE, connectionName),
+ IProgressMonitor.UNKNOWN);
+ IStatus status = connect(service, monitor);
+ monitor.setTaskName(MessageFormat.format("Connected to {0}",
getHostName(service)));
+ monitor.done();
+ return status;
+ } catch (Exception e) {
e.printStackTrace();
- // odd behavior: service reports connection failure even if things seem to work
(view opens up with connection in it)
+ // odd behavior: service reports connection failure even if
+ // things seem to work (view opens up with connection in it)
// ignore errors since things work
//
// return StatusFactory.getInstance(IStatus.ERROR,
@@ -182,14 +271,15 @@
@Override
public void run() {
try {
- UIUtils.showView(VIEW_REMOTESYSEXPLORER_ID);
+ WorkbenchUtils.showView(VIEW_REMOTESYSEXPLORER_ID);
} catch (PartInitException e) {
// I have no idea wtf is wrong here
// but my dev environment will not let me use common classes
-// IStatus status = StatusFactory.getInstance(IStatus.ERROR,
-// DeltaCloudIntegrationPlugin.PLUGIN_ID, e.getMessage(), e);
+ // IStatus status = StatusFactory.getInstance(IStatus.ERROR,
+ // DeltaCloudIntegrationPlugin.PLUGIN_ID, e.getMessage(),
+ // e);
Status status = new Status(IStatus.ERROR, DeltaCloudIntegrationPlugin.PLUGIN_ID,
e.getMessage(), e);
- ErrorDialog.openError(UIUtils.getActiveShell(),
+ ErrorDialog.openError(WorkbenchUtils.getActiveShell(),
Messages.ERROR,
Messages.COULD_NOT_LAUNCH_RSE_EXPLORER,
status);
@@ -197,9 +287,17 @@
}
});
}
-
+
public static IRemoteFileSubSystem findRemoteFileSubSystem(IHost host) {
- return CreateServerFromRSEJob.findRemoteFileSubSystem(host);
+ if (host == null) {
+ return null;
+ }
+ ISubSystem[] systems = RSECorePlugin.getTheSystemRegistry().getSubSystems(host);
+ for (int i = 0; i < systems.length; i++) {
+ if (systems[i] instanceof IRemoteFileSubSystem) {
+ return (IRemoteFileSubSystem) systems[i];
+ }
+ }
+ return null;
}
-
}
Added:
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.ui/src/org/jboss/tools/internal/deltacloud/ui/utils/WorkbenchUtils.java
===================================================================
---
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.ui/src/org/jboss/tools/internal/deltacloud/ui/utils/WorkbenchUtils.java
(rev 0)
+++
branches/jbosstools-3.2.x/deltacloud/plugins/org.jboss.tools.deltacloud.ui/src/org/jboss/tools/internal/deltacloud/ui/utils/WorkbenchUtils.java 2011-02-24
05:18:05 UTC (rev 29301)
@@ -0,0 +1,337 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at
http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.internal.deltacloud.ui.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.ContributionManager;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.menus.IMenuService;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author Andre Dietisheim
+ */
+public class WorkbenchUtils {
+
+ private static final String CONTEXT_MENU_PREFIX = "popup:";
+ private static final String VIEW_MENU_PREFIX = "menu:";
+
+ private WorkbenchUtils() {
+ }
+
+ /**
+ * Returns the selection of the active workbench window.
+ *
+ * @return the selection
+ *
+ * @see IWorkbenchWindow#getSelectionService()
+ */
+ public static ISelection getWorkbenchWindowSelection() {
+ return getActiveWorkbenchWindow().getSelectionService().getSelection();
+ }
+
+ /**
+ * Gets the structured selection.
+ *
+ * @return the structured selection
+ */
+ public static IStructuredSelection getStructuredSelection() {
+ ISelection selection = getWorkbenchWindowSelection();
+ if (selection instanceof IStructuredSelection) {
+ return (IStructuredSelection) selection;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the first element of a given selection in the given type. Returns
+ * <code>null</null> if selection is selection is empty or adaption of the
first element in
+ * the given selection fails. Adaption is tried by casting and by adapting it.
+ *
+ * @param selection
+ * the selection
+ * @param expectedClass
+ * the expected class
+ *
+ * @return the first element
+ */
+ public static <T> T getFirstAdaptedElement(final ISelection selection, final
Class<T> expectedClass) {
+ if (selection == null
+ || !(selection instanceof IStructuredSelection)) {
+ return null;
+ } else {
+ Object firstElement = ((IStructuredSelection) selection).getFirstElement();
+ if (firstElement == null) {
+ return null;
+ }
+ return adapt(firstElement, expectedClass);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the given selection holds exactly 1 element
+ * of the given type.
+ *
+ * @param selection
+ * the selection to check
+ * @param expectedClass
+ * the expected class
+ * @return <code>true</code>, if the given selection holds a single element
+ * of the given type.
+ */
+ public static <T> boolean isSingleSelection(final ISelection selection, final
Class<T> expectedClass) {
+ if (!(selection instanceof IStructuredSelection)) {
+ return false;
+ }
+
+ return ((IStructuredSelection) selection).toList().size() == 1
+ && getFirstAdaptedElement(selection, expectedClass) != null;
+ }
+
+ public static <T> List<T> adapt(Collection<?> objects, Class<T>
expectedClass) {
+ List<T> adaptedObjects = new ArrayList<T>();
+ for (Object object : objects) {
+ T adaptedObject = adapt(object, expectedClass);
+ if (adaptedObject != null) {
+ adaptedObjects.add(adaptedObject);
+ }
+ }
+ return adaptedObjects;
+ }
+
+ /**
+ * Adapts the given object to the given type. Returns <code>null</code> if
+ * the given adaption is not possible. Adaption is tried by casting and by
+ * adapting it.
+ *
+ * @param <T>
+ * @param object
+ * @param expectedClass
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T adapt(Object object, Class<T> expectedClass) {
+ if (object == null) {
+ return null;
+ }
+
+ Object adaptedObject = null;
+ if (expectedClass.isAssignableFrom(object.getClass())) {
+ adaptedObject = object;
+ } else if (object instanceof IAdaptable) {
+ adaptedObject = ((IAdaptable) object).getAdapter(expectedClass);
+ }
+
+ if (adaptedObject != null) {
+ return (T) adaptedObject;
+ } else {
+ return (T) Platform.getAdapterManager().loadAdapter(object, expectedClass.getName());
+ }
+ }
+
+ /**
+ * Gets the active page.
+ *
+ * @return the active page
+ */
+ public static IWorkbenchPage getActivePage() {
+ IWorkbenchPage workbenchPage = getActiveWorkbenchWindow().getActivePage();
+ Assert.isNotNull(workbenchPage);
+ return workbenchPage;
+ }
+
+ /**
+ * Returns the editor that's currently active (focused).
+ *
+ * @return the active editor
+ */
+ public static IEditorPart getActiveEditor() {
+ IEditorPart editor = getActivePage().getActiveEditor();
+ Assert.isNotNull(editor);
+ return editor;
+ }
+
+ /**
+ * Gets the active workbench window.
+ *
+ * @return the active workbench window
+ */
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ IWorkbenchWindow workbenchWindow = getWorkbench().getActiveWorkbenchWindow();
+ Assert.isNotNull(workbenchWindow);
+ return workbenchWindow;
+ }
+
+ public static Shell getActiveShell() {
+ Shell shell = getActiveWorkbenchWindow().getShell();
+ Assert.isTrue(shell != null && !shell.isDisposed());
+ return shell;
+ }
+
+ /**
+ * Gets the workbench.
+ *
+ * @return the workbench
+ */
+ public static IWorkbench getWorkbench() {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ Assert.isNotNull(workbench);
+ return workbench;
+ }
+
+ /**
+ * Replaces an image with the given key by the given image descriptor.
+ *
+ * @param imageKey
+ * the image key
+ * @param imageDescriptor
+ * the image descriptor
+ */
+ public static void replaceInJfaceImageRegistry(final String imageKey, final
ImageDescriptor imageDescriptor) {
+ Assert.isNotNull(imageKey);
+ Assert.isNotNull(imageDescriptor);
+
+ JFaceResources.getImageRegistry().remove(imageKey);
+ JFaceResources.getImageRegistry().put(imageKey, imageDescriptor);
+ }
+
+ /**
+ * Register the given ContributionManager with the given id. The
+ * contribution manager gets unregistered on control disposal.
+ *
+ * @param id
+ * the id
+ * @param contributionManager
+ * the contribution manager
+ * @param control
+ * the control
+ *
+ * @see ContributionManager
+ * @see IMenuService
+ * @see DisposeListener
+ */
+ public static void registerContributionManager(final String id, final
IContributionManager contributionManager,
+ final Control control) {
+ Assert.isNotNull(id);
+ Assert.isNotNull(contributionManager);
+ Assert.isTrue(control != null && !control.isDisposed());
+
+ final IMenuService menuService = (IMenuService)
PlatformUI.getWorkbench().getService(IMenuService.class);
+ menuService.populateContributionManager((ContributionManager) contributionManager,
id);
+ contributionManager.update(true);
+ control.addDisposeListener(new DisposeListener()
+ {
+ public void widgetDisposed(DisposeEvent e)
+ {
+ menuService.releaseContributions((ContributionManager) contributionManager);
+ }
+ });
+ }
+
+ public static String getContextMenuId(String viewId) {
+ return new StringBuffer(CONTEXT_MENU_PREFIX).append(viewId).toString();
+ }
+
+ public static String getViewMenuId(String viewId) {
+ return new StringBuffer(VIEW_MENU_PREFIX).append(viewId).toString();
+ }
+
+ /**
+ * Creates context menu to a given control.
+ *
+ * @param control
+ * the control
+ *
+ * @return the i menu manager
+ */
+ public static IMenuManager createContextMenu(final Control control) {
+ Assert.isTrue(control != null && !control.isDisposed());
+
+ MenuManager menuManager = new MenuManager();
+ menuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+
+ Menu menu = menuManager.createContextMenu(control);
+ control.setMenu(menu);
+ return menuManager;
+ }
+
+ /**
+ * Gets the dialog settings for the given identifer and plugin.
+ *
+ * @param identifier
+ * the identifier
+ * @param plugin
+ * the plugin
+ *
+ * @return the dialog settings
+ */
+ public static IDialogSettings getDialogSettings(final String identifier, final
AbstractUIPlugin plugin) {
+ Assert.isNotNull(plugin);
+ IDialogSettings dialogSettings = plugin.getDialogSettings();
+ IDialogSettings section = dialogSettings.getSection(identifier);
+ if (section == null) {
+ section = dialogSettings.addNewSection(identifier);
+ }
+ return section;
+ }
+
+ /**
+ * Returns the page for a given editor.
+ *
+ * @param editor
+ * the editor
+ * @return
+ *
+ * @return the page
+ *
+ * @see IWorkbenchPage
+ */
+ public static IWorkbenchPage getPage(EditorPart editor) {
+ Assert.isNotNull(editor);
+ IWorkbenchPartSite site = editor.getSite();
+ Assert.isNotNull(site);
+ return site.getPage();
+ }
+
+ public static void showView(String viewId) throws PartInitException {
+ Assert.isLegal(viewId != null && viewId.length() > 0);
+ getActivePage().showView(viewId);
+ }
+}