From 6cd50c21dd97a32f3cfce2e7ab2c51b4340c15fb Mon Sep 17 00:00:00 2001 From: David McKnight Date: Wed, 16 Jan 2008 18:35:39 +0000 Subject: [PATCH] [209593] [api] add support for "file permissions" and "owner" properties for unix files --- .../plugin.properties | 2 + .../org.eclipse.rse.files.ui/plugin.xml | 20 +- .../rse/internal/files/ui/FileResources.java | 18 + .../files/ui/FileResources.properties | 24 + .../SystemFilePermissionsPropertyPage.java | 533 ++++++++++++++++++ .../ui/view/SystemViewRemoteFileAdapter.java | 195 ++++++- .../miners/IUniversalDataStoreConstants.java | 12 +- .../miners/UniversalFileSystemMiner.java | 329 ++++++++++- .../dstore/files/DStoreFileService.java | 172 +++++- .../services/files/HostFilePermissions.java | 86 +++ .../rse/services/files/IFileOwnerService.java | 83 +++ .../files/IFilePermissionsService.java | 64 +++ .../services/files/IHostFilePermissions.java | 122 ++++ .../plugin.xml | 14 + .../RemoteFilePermissionsAdapterFactory.java | 65 +++ .../files/core/subsystems/IRemoteFile.java | 22 +- .../files/core/subsystems/RemoteFile.java | 41 +- 17 files changed, 1781 insertions(+), 21 deletions(-) create mode 100644 rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/propertypages/SystemFilePermissionsPropertyPage.java create mode 100644 rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/HostFilePermissions.java create mode 100644 rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileOwnerService.java create mode 100644 rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFilePermissionsService.java create mode 100644 rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IHostFilePermissions.java create mode 100644 rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/internal/subsystems/files/core/RemoteFilePermissionsAdapterFactory.java diff --git a/rse/plugins/org.eclipse.rse.files.ui/plugin.properties b/rse/plugins/org.eclipse.rse.files.ui/plugin.properties index ca28ea3d608..59861cc3b0c 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/plugin.properties +++ b/rse/plugins/org.eclipse.rse.files.ui/plugin.properties @@ -14,6 +14,7 @@ # Contributors: # Willian Mitsuda - [184824] added a Remote action set item # David McKnight (IBM) - [187711] Link with Editor action for System View +# David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files ############################################################################### # NLS_MESSAGEFORMAT_NONE @@ -26,6 +27,7 @@ PreferencePage.UniversalFiles = Files PreferencePage.Cache = File Cache RemotePropertyPage.File.Info = Info +RemotePropertyPage.File.Permissions = Permissions PropertyPage.ServerLauncherSettings = Server Launcher Settings PropertyPage.Service = Service diff --git a/rse/plugins/org.eclipse.rse.files.ui/plugin.xml b/rse/plugins/org.eclipse.rse.files.ui/plugin.xml index a85a51862dd..7f5f9a68468 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/plugin.xml +++ b/rse/plugins/org.eclipse.rse.files.ui/plugin.xml @@ -16,6 +16,8 @@ Martin Oberhuber (Wind River) - [180519] declaratively register adapter factorie Martin Oberhuber (Wind River) - [168975] Move RSE Events API to Core Martin Oberhuber (Wind River) - [186748] Move ISubSystemConfigurationAdapter from UI/rse.core.subsystems.util David McKnight (IBM) - [187711] Link with Editor action for System View +David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files + --> @@ -109,9 +111,8 @@ David McKnight (IBM) - [187711] Link with Editor action for System View - - + - + + + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.java index dc61779b713..4aaabb9de55 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.java @@ -13,6 +13,7 @@ * Contributors: * David Dykstal (IBM) - 176488: adding some text for the cache limit checkbox * David McKnight(IBM) - [210142] for accessibility need transfer mode toggle button + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files ********************************************************************************/ package org.eclipse.rse.internal.files.ui; @@ -265,7 +266,24 @@ public class FileResources extends NLS public static String MESSAGE_EXPANDING_FILTER; public static String MESSSAGE_QUERYING_FILE; + // file permisssions property page + public static String MESSAGE_FILE_PERMISSIONS_NOT_SUPPORTED; + public static String RESID_PREF_PERMISSIONS_PERMISSIONS_LABEL; + public static String RESID_PREF_PERMISSIONS_TYPE_LABEL; + public static String RESID_PREF_PERMISSIONS_READ_LABEL; + public static String RESID_PREF_PERMISSIONS_WRITE_LABEL; + public static String RESID_PREF_PERMISSIONS_EXECUTE_LABEL; + public static String RESID_PREF_PERMISSIONS_USER_LABEL; + public static String RESID_PREF_PERMISSIONS_GROUP_LABEL; + public static String RESID_PREF_PERMISSIONS_OTHERS_LABEL; + public static String RESID_PREF_PERMISSIONS_OWNERSHIP_LABEL; + // file permissions messages + public static String MESSAGE_PENDING; + public static String MESSAGE_NOT_SUPPORTED; + public static String MESSAGE_GETTING_PERMISSIONS; + public static String MESSAGE_GETTING_OWNER; + public static String MESSAGE_GETTING_GROUP; static { diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.properties b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.properties index b4a48840452..35d340cd7d6 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.properties +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/FileResources.properties @@ -13,6 +13,7 @@ # Contributors: # David Dykstal (IBM) - 176488: adding some text for the cache limit checkbox # David McKnight(IBM) - [210142] for accessibility need transfer mode toggle button +# David McKnight(IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files ################################################################################ # NLS_MESSAGEFORMAT_VAR @@ -262,3 +263,26 @@ MESSAGE_EXPANDING_FOLDER=Expanding Folder... MESSAGE_EXPANDING_FILTER=Expanding Filter... MESSSAGE_QUERYING_FILE=Querying File... +#============================================================= +# File Permissions Property Page... +#============================================================= +MESSAGE_FILE_PERMISSIONS_NOT_SUPPORTED=Permissions and ownership not supported +RESID_PREF_PERMISSIONS_PERMISSIONS_LABEL=Permissions +RESID_PREF_PERMISSIONS_TYPE_LABEL=Type +RESID_PREF_PERMISSIONS_READ_LABEL=Read +RESID_PREF_PERMISSIONS_WRITE_LABEL=Write +RESID_PREF_PERMISSIONS_EXECUTE_LABEL=Execute +RESID_PREF_PERMISSIONS_USER_LABEL=User +RESID_PREF_PERMISSIONS_GROUP_LABEL=Group +RESID_PREF_PERMISSIONS_OTHERS_LABEL=Others +RESID_PREF_PERMISSIONS_OWNERSHIP_LABEL=Ownership + +#============================================================= +# File Permissions Messages... +#============================================================= +MESSAGE_PENDING=Pending... +MESSAGE_NOT_SUPPORTED=Not supported +MESSAGE_GETTING_PERMISSIONS=Getting Permissions +MESSAGE_GETTING_OWNER=Getting Owner +MESSAGE_GETTING_GROUP=Getting Group + diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/propertypages/SystemFilePermissionsPropertyPage.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/propertypages/SystemFilePermissionsPropertyPage.java new file mode 100644 index 00000000000..20ffa58b7ac --- /dev/null +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/propertypages/SystemFilePermissionsPropertyPage.java @@ -0,0 +1,533 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are 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 + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files + ********************************************************************************/ +package org.eclipse.rse.internal.files.ui.propertypages; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.rse.core.RSECorePlugin; +import org.eclipse.rse.core.events.ISystemResourceChangeEvents; +import org.eclipse.rse.core.events.SystemResourceChangeEvent; +import org.eclipse.rse.core.model.ISystemRegistry; +import org.eclipse.rse.internal.files.ui.FileResources; +import org.eclipse.rse.services.files.IFileOwnerService; +import org.eclipse.rse.services.files.IFilePermissionsService; +import org.eclipse.rse.services.files.IHostFilePermissions; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.subsystems.files.core.subsystems.RemoteFile; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.propertypages.SystemBasePropertyPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * Property page for viewing and changing the user, group and permissions + * for a particular file. + * */ +public class SystemFilePermissionsPropertyPage extends SystemBasePropertyPage { + + private Button _userRead; + private Button _userWrite; + private Button _userExecute; + private Button _groupRead; + private Button _groupWrite; + private Button _groupExecute; + private Button _otherRead; + private Button _otherWrite; + private Button _otherExecute; + + private Text _userEntry; + private Text _groupEntry; + + private IHostFilePermissions _permissions; + private String _owner; + private String _group; + + /** + * Get the input remote file object + */ + protected IRemoteFile getRemoteFile() + { + Object element = getElement(); + return ((IRemoteFile)element); + } + + protected Control createContentArea(Composite parent) { + + + // Inner composite + Composite composite_prompts = SystemWidgetHelpers.createComposite(parent, 1); + + IRemoteFile file = getRemoteFile(); + IFilePermissionsService service = getPermissionsService(file); + if (service == null || !service.canGetFilePermissions(file.getParentPath(), file.getName())){ + // not supported + SystemWidgetHelpers.createLabel(parent, FileResources.MESSAGE_FILE_PERMISSIONS_NOT_SUPPORTED); + } + else + { + Group permissionsGroup = SystemWidgetHelpers.createGroupComposite(composite_prompts,4, FileResources.RESID_PREF_PERMISSIONS_PERMISSIONS_LABEL); + GridData data = new GridData(); + data.horizontalSpan = 5; + data.horizontalAlignment = SWT.FILL; + data.grabExcessHorizontalSpace = false; + data.verticalAlignment = SWT.BEGINNING; + data.grabExcessVerticalSpace = false; + permissionsGroup.setLayoutData(data); + + Label userTypeLabel = SystemWidgetHelpers.createLabel(permissionsGroup, FileResources.RESID_PREF_PERMISSIONS_TYPE_LABEL); + + Label readLabel = SystemWidgetHelpers.createLabel(permissionsGroup, FileResources.RESID_PREF_PERMISSIONS_READ_LABEL); + data = new GridData(); + data.horizontalIndent = 20; + readLabel.setLayoutData(data); + + Label writeLabel = SystemWidgetHelpers.createLabel(permissionsGroup, FileResources.RESID_PREF_PERMISSIONS_WRITE_LABEL); + data = new GridData(); + data.horizontalIndent = 20; + writeLabel.setLayoutData(data); + + Label executeLabel = SystemWidgetHelpers.createLabel(permissionsGroup, FileResources.RESID_PREF_PERMISSIONS_EXECUTE_LABEL); + data = new GridData(); + data.horizontalIndent = 20; + executeLabel.setLayoutData(data); + + + Label userLabel = SystemWidgetHelpers.createLabel(permissionsGroup, FileResources.RESID_PREF_PERMISSIONS_USER_LABEL); + _userRead = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _userRead.setLayoutData(data); + + _userWrite = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _userWrite.setLayoutData(data); + + _userExecute = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _userExecute.setLayoutData(data); + + Label groupLabel = SystemWidgetHelpers.createLabel(permissionsGroup, FileResources.RESID_PREF_PERMISSIONS_GROUP_LABEL); + + _groupRead = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _groupRead.setLayoutData(data); + + _groupWrite = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _groupWrite.setLayoutData(data); + + _groupExecute = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _groupExecute.setLayoutData(data); + + Label otherLabel = SystemWidgetHelpers.createLabel(permissionsGroup, FileResources.RESID_PREF_PERMISSIONS_OTHERS_LABEL); + _otherRead = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _otherRead.setLayoutData(data); + + _otherWrite = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _otherWrite.setLayoutData(data); + + _otherExecute = new Button(permissionsGroup, SWT.CHECK); + data = new GridData(); + data.horizontalIndent = 20; + _otherExecute.setLayoutData(data); + + Group ownerGroup = SystemWidgetHelpers.createGroupComposite(composite_prompts, 2, FileResources.RESID_PREF_PERMISSIONS_OWNERSHIP_LABEL); + data = new GridData(); + data.horizontalSpan = 1; + data.verticalSpan = 5; + data.horizontalAlignment = SWT.FILL; + data.grabExcessHorizontalSpace = false; + data.verticalAlignment = SWT.BEGINNING; + data.grabExcessVerticalSpace = false; + ownerGroup.setLayoutData(data); + + Label userOwnerLabel = SystemWidgetHelpers.createLabel(ownerGroup, FileResources.RESID_PREF_PERMISSIONS_USER_LABEL); + _userEntry = new Text(ownerGroup, SWT.BORDER); + data = new GridData(); + data.widthHint = 100; + _userEntry.setLayoutData(data); + + Label groupOwnerLabel = SystemWidgetHelpers.createLabel(ownerGroup, FileResources.RESID_PREF_PERMISSIONS_GROUP_LABEL); + _groupEntry = new Text(ownerGroup, SWT.BORDER); + data = new GridData(); + data.widthHint = 100; + _groupEntry.setLayoutData(data); + + + initFields(); + } + + return composite_prompts; + } + + protected boolean verifyPageContents() { + return true; + } + + private void enableOwnershipFields(boolean enabled) { + + _userEntry.setEnabled(enabled); + _groupEntry.setEnabled(enabled); + } + + private void enablePermissionFields(boolean enabled){ + + _groupExecute.setEnabled(enabled); + _groupRead.setEnabled(enabled); + _groupWrite.setEnabled(enabled); + + _userExecute.setEnabled(enabled); + _userRead.setEnabled(enabled); + _userWrite.setEnabled(enabled); + + _otherExecute.setEnabled(enabled); + _otherRead.setEnabled(enabled); + _otherWrite.setEnabled(enabled); + } + + private IFilePermissionsService getPermissionsService(IRemoteFile remoteFile){ + + if (remoteFile instanceof IAdaptable){ + return (IFilePermissionsService)((IAdaptable)remoteFile).getAdapter(IFilePermissionsService.class); + } + + return null; + } + + + private IFileOwnerService getOwnerService(IRemoteFile remoteFile){ + + if (remoteFile instanceof IAdaptable){ + return (IFileOwnerService)((IAdaptable)remoteFile).getAdapter(IFileOwnerService.class); + } + + return null; + } + + + private void initFields() { + IRemoteFile remoteFile = getRemoteFile(); + + IFilePermissionsService ps = getPermissionsService(remoteFile); + if (ps == null){ + enablePermissionFields(false); + } + else { + initPermissionFields(remoteFile, ps); + } + + IFileOwnerService os = getOwnerService(remoteFile); + if (ps == null){ + enableOwnershipFields(false); + } + else { + initOwnershipFields(remoteFile, os); + } + } + + private void initPermissionFields(IRemoteFile file, IFilePermissionsService service){ + _permissions = null; // null set so that we make sure we're getting fresh permissions + + final IRemoteFile rFile = file; + final IFilePermissionsService pService = service; + String remoteParent = file.getParentPath(); + String name = file.getName(); + + if (service.canGetFilePermissions(remoteParent, name)){ + enablePermissionFields(true); + try + { + _permissions = file.getPermissions(); + if (_permissions == null){ + Job deferredFetch = new Job(FileResources.MESSAGE_GETTING_PERMISSIONS) + { + public IStatus run(IProgressMonitor monitor){ + try + { + String remoteParent = rFile.getParentPath(); + String fname = rFile.getName(); + _permissions = pService.getFilePermissions(remoteParent, fname, monitor); + if (_permissions != null && rFile instanceof RemoteFile){ + ((RemoteFile)rFile).setPermissions(_permissions); + } + + // notify change + Display.getDefault().asyncExec(new Runnable() + { + public void run() + { + _userRead.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_USER_READ)); + _userWrite.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_USER_WRITE)); + _userExecute.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_USER_EXECUTE)); + _groupRead.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_GROUP_READ)); + _groupWrite.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_GROUP_WRITE)); + _groupExecute.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_GROUP_EXECUTE)); + _otherRead.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_OTHER_READ)); + _otherWrite.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_OTHER_WRITE)); + _otherExecute.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_OTHER_EXECUTE)); + } + }); + } + catch (Exception e) + { + } + return Status.OK_STATUS; + } + }; + deferredFetch.schedule(); + } + else { + _userRead.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_USER_READ)); + _userWrite.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_USER_WRITE)); + _userExecute.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_USER_EXECUTE)); + _groupRead.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_GROUP_READ)); + _groupWrite.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_GROUP_WRITE)); + _groupExecute.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_GROUP_EXECUTE)); + _otherRead.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_OTHER_READ)); + _otherWrite.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_OTHER_WRITE)); + _otherExecute.setSelection(_permissions.getPermission(IHostFilePermissions.PERM_OTHER_EXECUTE)); + } + } + catch (Exception e){ + + } + } + else { + enablePermissionFields(false); + } + } + + + private void initOwnershipFields(IRemoteFile file, IFileOwnerService service){ + _owner = null; + _group = null; + + String remoteParent = file.getParentPath(); + String name = file.getName(); + final IRemoteFile rFile = file; + final IFileOwnerService oService = service; + + if (service.canGetFileOwner(remoteParent, name)){ + enableOwnershipFields(true); + try + { + _owner = file.getOwner(); + if (_owner == null){ + Job deferredFetch = new Job(FileResources.MESSAGE_GETTING_OWNER) + { + public IStatus run(IProgressMonitor monitor){ + try + { + String remoteParent = rFile.getParentPath(); + String fname = rFile.getName(); + _owner = oService.getFileUserOwner(remoteParent, fname, monitor); + if (_owner != null && rFile instanceof RemoteFile){ + ((RemoteFile)rFile).setOwner(_owner); + } + + // notify change + Display.getDefault().asyncExec(new Runnable() + { + public void run() + { + _userEntry.setText(_owner); + } + }); + } + catch (Exception e) + { + } + return Status.OK_STATUS; + } + }; + deferredFetch.schedule(); + _userEntry.setText(FileResources.MESSAGE_PENDING); + } + else { + _userEntry.setText(_owner); + } + + _group = file.getGroup(); + if (_group == null){ + Job deferredFetch = new Job(FileResources.MESSAGE_GETTING_GROUP) + { + public IStatus run(IProgressMonitor monitor){ + try + { + String remoteParent = rFile.getParentPath(); + String fname = rFile.getName(); + _group = oService.getFileGroupOwner(remoteParent, fname, monitor); + if (_group != null && rFile instanceof RemoteFile){ + ((RemoteFile)rFile).setGroup(_group); + } + + // notify change + Display.getDefault().asyncExec(new Runnable() + { + public void run() + { + _groupEntry.setText(_group); + } + }); + + } + catch (Exception e) + { + } + return Status.OK_STATUS; + } + }; + deferredFetch.schedule(); + _groupEntry.setText(FileResources.MESSAGE_PENDING); + } + else { + _groupEntry.setText(_group); + } + } + catch (Exception e){ + + } + } + else { + enableOwnershipFields(false); + } + } + + public boolean performOk() { + IRemoteFile remoteFile = getRemoteFile(); + + boolean changed = false; + + // permission changes + if (_permissions != null){ + IFilePermissionsService service = getPermissionsService(remoteFile); + + String remoteParent = remoteFile.getParentPath(); + String name = remoteFile.getName(); + + + if (service.canSetFilePermissions(remoteParent, name)){ + try + { + + + if (_permissions.getPermission(IHostFilePermissions.PERM_USER_READ) != _userRead.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_USER_READ, _userRead.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_USER_WRITE) != _userWrite.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_USER_WRITE, _userWrite.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_USER_EXECUTE) != _userExecute.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_USER_EXECUTE, _userExecute.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_GROUP_READ) != _groupRead.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_GROUP_READ, _groupRead.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_GROUP_WRITE) != _groupWrite.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_GROUP_WRITE, _groupWrite.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_GROUP_EXECUTE) != _groupExecute.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_GROUP_EXECUTE, _groupExecute.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_OTHER_READ) != _otherRead.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_OTHER_READ, _otherRead.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_OTHER_WRITE) != _otherWrite.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_OTHER_WRITE, _otherWrite.getSelection()); + } + if (_permissions.getPermission(IHostFilePermissions.PERM_OTHER_EXECUTE) != _otherExecute.getSelection()){ + changed = true; + _permissions.setPermission(IHostFilePermissions.PERM_OTHER_EXECUTE, _otherExecute.getSelection()); + } + + if (changed){ + service.setFilePermissions(remoteParent, name, _permissions, new NullProgressMonitor()); + } + } + catch (Exception e){ + + } + } + } + if (_owner != null){ + IFileOwnerService service = getOwnerService(remoteFile); + + String remoteParent = remoteFile.getParentPath(); + String name = remoteFile.getName(); + + if (service.canSetFileOwner(remoteParent, name)){ + try + { + if (_owner != _userEntry.getText()){ + changed = true; + if (remoteFile instanceof RemoteFile){ + ((RemoteFile)remoteFile).setOwner(_owner); + } + + service.setFileUserOwner(remoteParent, name, _userEntry.getText(), new NullProgressMonitor()); + } + if (_group != _groupEntry.getText()){ + changed = true; + if (remoteFile instanceof RemoteFile){ + ((RemoteFile)remoteFile).setGroup(_group); + } + service.setFileGroupOwner(remoteParent, name, _groupEntry.getText(), new NullProgressMonitor()); + } + } + catch (Exception e){ + + } + } + } + + if (changed){ + // notify views of change + ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry(); + registry.fireEvent(new SystemResourceChangeEvent(remoteFile, ISystemResourceChangeEvents.EVENT_PROPERTY_CHANGE, remoteFile)); + } + + + return super.performOk(); + } + +} diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java index 98ddd603cbc..cb031063d25 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java @@ -42,6 +42,7 @@ * Xuan Chen (IBM) - [209827] Update DStore command implementation to enable cancelation of archive operations * Xuan Chen (IBM) - [191370] [dstore] Supertransfer zip not deleted when cancelling copy * David McKnight (IBM) - [189873] DownloadJob changed to DownloadAndOpenJob + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files ********************************************************************************/ package org.eclipse.rse.internal.files.ui.view; @@ -58,9 +59,12 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.resource.ImageDescriptor; @@ -68,6 +72,8 @@ import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.rse.core.RSECorePlugin; +import org.eclipse.rse.core.events.ISystemResourceChangeEvents; +import org.eclipse.rse.core.events.SystemResourceChangeEvent; import org.eclipse.rse.core.filters.ISystemFilter; import org.eclipse.rse.core.filters.ISystemFilterReference; import org.eclipse.rse.core.filters.SystemFilterReference; @@ -110,6 +116,9 @@ import org.eclipse.rse.services.clientserver.SystemSearchString; import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager; import org.eclipse.rse.services.clientserver.messages.SystemMessage; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; +import org.eclipse.rse.services.files.IFileOwnerService; +import org.eclipse.rse.services.files.IFilePermissionsService; +import org.eclipse.rse.services.files.IHostFilePermissions; import org.eclipse.rse.services.search.HostSearchResultSet; import org.eclipse.rse.services.search.IHostSearchConstants; import org.eclipse.rse.services.search.IHostSearchResultConfiguration; @@ -885,7 +894,7 @@ public class SystemViewRemoteFileAdapter int nbrOfArchiveProperties = 2; int nbrOfVirtualProperties = 4; - int nbrOfProperties = 5; + int nbrOfProperties = 8; if (isVirtual) nbrOfProperties += nbrOfVirtualProperties; else if (isArchive) nbrOfProperties += nbrOfArchiveProperties; @@ -924,7 +933,22 @@ public class SystemViewRemoteFileAdapter else if (isVirtual) uniqueVirtualDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_EXTENSION, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_LABEL, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_TOOLTIP); else if (isArchive) uniqueArchiveDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_EXTENSION, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_LABEL, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_TOOLTIP); - + // file permissions + if (isRegular) uniquePropertyDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_PERMISSIONS, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_LABEL, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_TOOLTIP); + else if (isVirtual) uniqueVirtualDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_PERMISSIONS, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_LABEL, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_TOOLTIP); + else if (isArchive) uniqueArchiveDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_PERMISSIONS, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_LABEL, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_TOOLTIP); + + // file owner + if (isRegular) uniquePropertyDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_OWNER, SystemViewResources.RESID_PROPERTY_FILE_OWNER_LABEL, SystemViewResources.RESID_PROPERTY_FILE_OWNER_TOOLTIP); + else if (isVirtual) uniqueVirtualDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_OWNER, SystemViewResources.RESID_PROPERTY_FILE_OWNER_LABEL, SystemViewResources.RESID_PROPERTY_FILE_OWNER_TOOLTIP); + else if (isArchive) uniqueArchiveDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_OWNER, SystemViewResources.RESID_PROPERTY_FILE_OWNER_LABEL, SystemViewResources.RESID_PROPERTY_FILE_OWNER_TOOLTIP); + + // file group + if (isRegular) uniquePropertyDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_GROUP, SystemViewResources.RESID_PROPERTY_FILE_GROUP_LABEL, SystemViewResources.RESID_PROPERTY_FILE_GROUP_TOOLTIP); + else if (isVirtual) uniqueVirtualDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_GROUP, SystemViewResources.RESID_PROPERTY_FILE_GROUP_LABEL, SystemViewResources.RESID_PROPERTY_FILE_GROUP_TOOLTIP); + else if (isArchive) uniqueArchiveDescriptorArray[++i] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_GROUP, SystemViewResources.RESID_PROPERTY_FILE_GROUP_LABEL, SystemViewResources.RESID_PROPERTY_FILE_GROUP_TOOLTIP); + + if (isVirtual) { // add virtual property descriptors... @@ -988,7 +1012,7 @@ public class SystemViewRemoteFileAdapter { int nbrOfArchiveProperties = 2; int nbrOfVirtualProperties = 4; - int nbrOfProperties = 9; + int nbrOfProperties = 12; int nbrOfBriefProperties = 2; if (debug) nbrOfProperties += 7; @@ -1050,7 +1074,22 @@ public class SystemViewRemoteFileAdapter if (isRegular) propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_EXTENSION, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_LABEL, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_TOOLTIP); else if (isVirtual) virtualDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_EXTENSION, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_LABEL, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_TOOLTIP); else if (isArchive) archiveDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_EXTENSION, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_LABEL, SystemViewResources.RESID_PROPERTY_FILE_EXTENSION_TOOLTIP); - + + // file permissions + if (isRegular) propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_PERMISSIONS, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_LABEL, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_TOOLTIP); + else if (isVirtual) virtualDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_PERMISSIONS, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_LABEL, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_TOOLTIP); + else if (isArchive) archiveDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_PERMISSIONS, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_LABEL, SystemViewResources.RESID_PROPERTY_FILE_PERMISSIONS_TOOLTIP); + + // file owner + if (isRegular) propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_OWNER, SystemViewResources.RESID_PROPERTY_FILE_OWNER_LABEL, SystemViewResources.RESID_PROPERTY_FILE_OWNER_TOOLTIP); + else if (isVirtual) virtualDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_OWNER, SystemViewResources.RESID_PROPERTY_FILE_OWNER_LABEL, SystemViewResources.RESID_PROPERTY_FILE_OWNER_TOOLTIP); + else if (isArchive) archiveDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_OWNER, SystemViewResources.RESID_PROPERTY_FILE_OWNER_LABEL, SystemViewResources.RESID_PROPERTY_FILE_OWNER_TOOLTIP); + + // file group + if (isRegular) propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_GROUP, SystemViewResources.RESID_PROPERTY_FILE_GROUP_LABEL, SystemViewResources.RESID_PROPERTY_FILE_GROUP_TOOLTIP); + else if (isVirtual) virtualDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_GROUP, SystemViewResources.RESID_PROPERTY_FILE_GROUP_LABEL, SystemViewResources.RESID_PROPERTY_FILE_GROUP_TOOLTIP); + else if (isArchive) archiveDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_FILE_GROUP, SystemViewResources.RESID_PROPERTY_FILE_GROUP_LABEL, SystemViewResources.RESID_PROPERTY_FILE_GROUP_TOOLTIP); + if (debug) { @@ -1266,10 +1305,130 @@ public class SystemViewRemoteFileAdapter { if(!file.isDirectory()) { String ext = file.getExtension(); - return ext == null?"":ext; + return ext == null?"":ext; //$NON-NLS-1$ } else - return ""; + return ""; //$NON-NLS-1$ + } + else if (name.equals(ISystemPropertyConstants.P_FILE_PERMISSIONS)) + { + IHostFilePermissions permissions = file.getPermissions(); + if (permissions == null){ + + if (file instanceof IAdaptable){ + final IFilePermissionsService service = (IFilePermissionsService)((IAdaptable)file).getAdapter(IFilePermissionsService.class); + if (service != null){ + final IRemoteFile rFile = file; + + + Job deferredFetch = new Job(FileResources.MESSAGE_GETTING_PERMISSIONS) + { + public IStatus run(IProgressMonitor monitor){ + try + { + String remoteParent = rFile.getParentPath(); + String fname = rFile.getName(); + IHostFilePermissions perm = service.getFilePermissions(remoteParent, fname, monitor); + if (perm != null && rFile instanceof RemoteFile){ + ((RemoteFile)rFile).setPermissions(perm); + // notify change to property sheet + + ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry(); + registry.fireEvent(new SystemResourceChangeEvent(rFile, ISystemResourceChangeEvents.EVENT_PROPERTY_CHANGE, rFile)); + } + } + catch (Exception e) + { + } + return Status.OK_STATUS; + } + }; + deferredFetch.schedule(); + return FileResources.MESSAGE_PENDING; + } + } + return FileResources.MESSAGE_NOT_SUPPORTED; + } + return permissions.toUserString(); + } + else if (name.equals(ISystemPropertyConstants.P_FILE_OWNER)) + { + String owner = file.getOwner(); + if (owner == null){ + if (file instanceof IAdaptable){ + + final IFileOwnerService service = (IFileOwnerService)((IAdaptable)file).getAdapter(IFileOwnerService.class); + if (service != null){ + + final IRemoteFile rFile = file; + + Job deferredFetch = new Job(FileResources.MESSAGE_GETTING_OWNER) + { + public IStatus run(IProgressMonitor monitor){ + try + { + String remoteParent = rFile.getParentPath(); + String fname = rFile.getName(); + String uowner = service.getFileUserOwner(remoteParent, fname, monitor); + if (uowner != null && rFile instanceof RemoteFile){ + ((RemoteFile)rFile).setOwner(uowner); + } + + // notify change to property sheet + ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry(); + registry.fireEvent(new SystemResourceChangeEvent(rFile, ISystemResourceChangeEvents.EVENT_PROPERTY_CHANGE, rFile)); + } + catch (Exception e) + { + } + return Status.OK_STATUS; + } + }; + deferredFetch.schedule(); + return FileResources.MESSAGE_PENDING; + } + } + return FileResources.MESSAGE_NOT_SUPPORTED; + } + return owner; + } + else if (name.equals(ISystemPropertyConstants.P_FILE_GROUP)) + { + String group = file.getGroup(); + if (group == null){ + if (file instanceof IAdaptable){ + final IFileOwnerService service = (IFileOwnerService)((IAdaptable)file).getAdapter(IFileOwnerService.class); + if (service != null){ + final IRemoteFile rFile = file; + + Job deferredFetch = new Job(FileResources.MESSAGE_GETTING_GROUP) + { + public IStatus run(IProgressMonitor monitor){ + try + { + String remoteParent = rFile.getParentPath(); + String fname = rFile.getName(); + String ugroup = service.getFileGroupOwner(remoteParent, fname, monitor); + if (ugroup != null && rFile instanceof RemoteFile){ + ((RemoteFile)rFile).setGroup(ugroup); + } + // notify change to property sheet + ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry(); + registry.fireEvent(new SystemResourceChangeEvent(rFile, ISystemResourceChangeEvents.EVENT_PROPERTY_CHANGE, rFile)); + } + catch (Exception e) + { + } + return Status.OK_STATUS; + } + }; + deferredFetch.schedule(); + return FileResources.MESSAGE_PENDING; + } + } + return FileResources.MESSAGE_NOT_SUPPORTED; + } + return group; } else if (name.equals(ISystemPropertyConstants.P_FILE_CLASSIFICATION)) { @@ -1665,6 +1824,13 @@ public class SystemViewRemoteFileAdapter if (submonitor != null) submonitor.worked(1); Object[] results = config.getResults(); + if (results == null || results.length == 0){ + // make sure search is really done + System.out.println("waiting for results"); //$NON-NLS-1$ + + } + + for (int m = 0; m < results.length; m++) { Object result = results[m]; @@ -1867,7 +2033,7 @@ public class SystemViewRemoteFileAdapter { if (thisObject instanceof IRemoteFile) { - copiedFileNames = copiedFileNames + "\n" + ((IRemoteFile)thisObject).getName(); + copiedFileNames = copiedFileNames + "\n" + ((IRemoteFile)thisObject).getName(); //$NON-NLS-1$ } } } @@ -2052,7 +2218,7 @@ public class SystemViewRemoteFileAdapter { if (thisObject instanceof IRemoteFile) { - copiedFileNames = copiedFileNames + "\n" + ((IRemoteFile)thisObject).getName(); + copiedFileNames = copiedFileNames + "\n" + ((IRemoteFile)thisObject).getName(); //$NON-NLS-1$ } } } @@ -3371,6 +3537,19 @@ public class SystemViewRemoteFileAdapter return tgt.isLink() && value.equals("true") || //$NON-NLS-1$ !tgt.isLink() && value.equals("false"); //$NON-NLS-1$ } + else if (inName.equals("supportspermissions")) //$NON-NLS-1$ + { + if (value.equals("true")){ //$NON-NLS-1$ + // check service + if (tgt instanceof IAdaptable){ + IFilePermissionsService service = (IFilePermissionsService)((IAdaptable)tgt).getAdapter(IFilePermissionsService.class); + if (service != null){ + return service.canGetFilePermissions(tgt.getParentPath(), tgt.getName()); + } + } + } + return false; + } else if (inName.equals("iscommandsubsystemexists")) { //$NON-NLS-1$ boolean test = value.equals("true"); //$NON-NLS-1$ diff --git a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/IUniversalDataStoreConstants.java b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/IUniversalDataStoreConstants.java index e317fb1051d..e1763878cbc 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/IUniversalDataStoreConstants.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/IUniversalDataStoreConstants.java @@ -96,8 +96,16 @@ public interface IUniversalDataStoreConstants public static final String C_QUERY_QUALIFIED_CLASSNAME = "C_QUERY_QUALIFIED_CLASSNAME"; //$NON-NLS-1$ public static final String TYPE_QUALIFIED_CLASSNAME = "fullClassName"; //$NON-NLS-1$ - - + // permissions commands + public static final String C_QUERY_FILE_PERMISSIONS = "C_QUERY_FILE_PERMISSIONS"; + public static final String C_SET_FILE_PERMISSIONS = "C_SET_FILE_PERMISSIONS"; + + // ownership commands + public static final String C_QUERY_FILE_USER_OWNER = "C_QUERY_FILE_USER_OWNER"; + public static final String C_SET_FILE_USER_OWNER = "C_SET_FILE_USER_OWNER"; + public static final String C_QUERY_FILE_GROUP_OWNER = "C_QUERY_FILE_GROUP_OWNER"; + public static final String C_SET_FILE_GROUP_OWNER = "C_SET_FILE_GROUP_OWNER"; + // Mode of transfer: text or binary public static final int TEXT_MODE = -1; public static final int BINARY_MODE = -2; diff --git a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java index 812cb622f03..ddfeda8ae1a 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002, 2008 IBM Corporation and others. + * Copyright (c) 2002, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -28,16 +28,19 @@ * David McKnight (IBM) - [196624] dstore miner IDs should be String constants rather than dynamic lookup * Xuan Chen (IBM) - [209827] Update DStore command implementation to enable cancelation of archive operations * Xuan Chen (IBM) - [194481] [dstore][Archive] Save Conflict After Renaming a File that is Open - * Xuan Chen (IBM) - [200417] [regression][dstore] Rename an expanded folder in an Archive displays no children + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files *******************************************************************************/ package org.eclipse.rse.dstore.universal.miners; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; import java.net.ServerSocket; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.StringTokenizer; import org.eclipse.dstore.core.miners.Miner; import org.eclipse.dstore.core.model.DE; @@ -58,6 +61,7 @@ import org.eclipse.rse.internal.dstore.universal.miners.filesystem.UniversalDown import org.eclipse.rse.internal.dstore.universal.miners.filesystem.UniversalSearchHandler; import org.eclipse.rse.services.clientserver.IClientServerConstants; import org.eclipse.rse.services.clientserver.IServiceConstants; +import org.eclipse.rse.services.clientserver.PathUtility; import org.eclipse.rse.services.clientserver.SystemFileClassifier; import org.eclipse.rse.services.clientserver.SystemSearchString; import org.eclipse.rse.services.clientserver.archiveutils.AbsoluteVirtualPath; @@ -207,6 +211,21 @@ public class UniversalFileSystemMiner extends Miner { return handleQueryClassName(subject, status); } else if (IUniversalDataStoreConstants.C_QUERY_QUALIFIED_CLASSNAME.equals(name)) { return handleQueryQualifiedClassName(subject, status); + } else if (IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS.equals(name)) { + return handleQueryFilePermissions(subject, status); + } else if (IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS.equals(name)) { + DataElement newPermissions = getCommandArgument(theElement, 1); + return handleSetFilePermissions(subject, newPermissions, status); + } else if (IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER.equals(name)) { + return handleQueryFileOwner(subject, status); + } else if (IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER.equals(name)) { + DataElement newOwner = getCommandArgument(theElement, 1); + return handleSetFileOwner(subject, newOwner, status); + } else if (IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER.equals(name)) { + return handleQueryFileGroupOwner(subject, status); + } else if (IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER.equals(name)) { + DataElement newOwner = getCommandArgument(theElement, 1); + return handleSetFileGroupOwner(subject, newOwner, status); } else { UniversalServerUtilities.logError(CLASSNAME, "Invalid query to handlecommand", null); //$NON-NLS-1$ @@ -1571,7 +1590,58 @@ public class UniversalFileSystemMiner extends Miner { // command descriptor to retrieve qualified class name for class file createCommandDescriptor(FileDescriptors._deUniversalFileObject, "GetFullClassName", //$NON-NLS-1$ IUniversalDataStoreConstants.C_QUERY_QUALIFIED_CLASSNAME); + + + // permissions and ownership not supported on windows + if (!_isWindows) { + // descriptors for permissions + createCommandDescriptor(UniversalFilter, "GetPermissions", IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFolderObject, "GetPermissions", IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFileObject, "GetPermissions", IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalArchiveFileObject, "GetPermissions",IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFileObject, "GetPermissions", IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFolderObject, "GetPermissions", IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS); //$NON-NLS-1$ + + createCommandDescriptor(UniversalFilter, "SetPermissions", IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFolderObject, "SetPermissions", IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFileObject, "SetPermissions", IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalArchiveFileObject, "SetPermissions",IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFileObject, "SetPermissions", IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFolderObject, "SetPermissions", IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS); //$NON-NLS-1$ + + + // descriptors for ownership + createCommandDescriptor(UniversalFilter, "GetOwner", IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFolderObject, "GetOwner", IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFileObject, "GetOwner", IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalArchiveFileObject, "GetOwner",IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFileObject, "GetOwner", IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFolderObject, "GetOwner", IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER); //$NON-NLS-1$ + + createCommandDescriptor(UniversalFilter, "SetOwner", IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFolderObject, "SetOwner", IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFileObject, "SetOwner", IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalArchiveFileObject, "SetOwner",IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFileObject, "SetOwner", IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFolderObject, "SetOwner", IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER); //$NON-NLS-1$ + + createCommandDescriptor(UniversalFilter, "GetGroupOwner", IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFolderObject, "GetGroupOwner", IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFileObject, "GetGroupOwner", IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalArchiveFileObject, "GetGroupOwner",IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFileObject, "GetGroupOwner", IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFolderObject, "GetGroupOwner", IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER); //$NON-NLS-1$ + + createCommandDescriptor(UniversalFilter, "SetGroupOwner", IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFolderObject, "SetGroupOwner", IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalFileObject, "SetGroupOwner", IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalArchiveFileObject, "SetGroupOwner",IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFileObject, "SetGroupOwner", IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER); //$NON-NLS-1$ + createCommandDescriptor(FileDescriptors._deUniversalVirtualFolderObject, "SetGroupOwner", IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER); //$NON-NLS-1$ + + } } + public AbsoluteVirtualPath getAbsoluteVirtualPath(DataElement subject) { StringBuffer path = new StringBuffer(subject.getAttribute(DE.A_VALUE)); @@ -1723,4 +1793,259 @@ public class UniversalFileSystemMiner extends Miner { { return "7.0.0"; //$NON-NLS-1$ } + + private File getFileFor(DataElement subject) + { + File fileobj = null; + boolean isVirtual = false; + boolean isFilter = false; + String fullName = subject.getValue(); + String queryType = subject.getType(); + if (queryType.equals(IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR)) + { + isFilter = true; + isVirtual = ArchiveHandlerManager.isVirtual(fullName); + String filterValue = subject.getValue(); + // . translates to home dir + if (filterValue.equals(".")) //$NON-NLS-1$ + { + filterValue = System.getProperty("user.home"); //$NON-NLS-1$ + subject.setAttribute(DE.A_VALUE, filterValue); + } + if (!isVirtual) + fileobj = new File(filterValue); + } + else if (queryType.equals(IUniversalDataStoreConstants.UNIVERSAL_FILE_DESCRIPTOR)) + { + String name = subject.getName(); + String path = subject.getValue(); + fileobj = new File(path, name); + } + else if (queryType.equals(IUniversalDataStoreConstants.UNIVERSAL_FOLDER_DESCRIPTOR)) + { + String name = subject.getName(); + String path = subject.getValue(); + if (name.length() == 0) + { + fileobj = new File(path); + } + else + { + fileobj = new File(path, name); + } + } + else if (queryType.equals(IUniversalDataStoreConstants.UNIVERSAL_ARCHIVE_FILE_DESCRIPTOR)) + { + String name = subject.getName(); + String path = subject.getValue(); + if (name.length() == 0) + { + fileobj = new File(path); + } + else + { + fileobj = new File(path, name); + } + } + else if (queryType.equals(IUniversalDataStoreConstants.UNIVERSAL_VIRTUAL_FILE_DESCRIPTOR) || queryType.equals(IUniversalDataStoreConstants.UNIVERSAL_VIRTUAL_FOLDER_DESCRIPTOR)) + { + isVirtual = true; + } + return fileobj; + } + + + /** + * Convert permissions in rwxrwxrwx form to octal + * @param userPermissions + * @return + */ + private String alphaPermissionsToOctal(String alphaPermissions) + { + StringBuffer buf = new StringBuffer(); + // permissions + char[] chars = alphaPermissions.toCharArray(); + + int offset = -1; + for (int i = 0; i < 3; i++){ + int value = 0; + + if (chars[++offset] == 'r'){ + value = 4; + } + if (chars[++offset] == 'w'){ + value += 2; + } + if (chars[++offset] == 'x'){ + value += 1; + } + buf.append(value); + } + + return buf.toString(); + } + + + private DataElement handleQueryFilePermissions(DataElement subject, DataElement status) + { + File file = getFileFor(subject); + + String result = null; + String os = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ + + if (os.startsWith("linux")){ //$NON-NLS-1$ + // permissions in octal form + result = simpleShellCommand("stat -c%a", file); //$NON-NLS-1$ + } + else { + // permissions in form "drwxrwxrwx ..." + String ldStr = simpleShellCommand("ls -ld", file); //$NON-NLS-1$ + + int firstSpace = ldStr.indexOf(' '); + + // permissions in form "rwxrwxrwx" + String permString = ldStr.substring(1, firstSpace); + result = alphaPermissionsToOctal(permString); + } + + status.setAttribute(DE.A_SOURCE, result); + statusDone(status); + + return status; + } + + private DataElement handleSetFilePermissions(DataElement subject, DataElement newPermissions, DataElement status) + { + File file = getFileFor(subject); + String result = simpleShellCommand("chmod " + newPermissions.getName(), file); //$NON-NLS-1$ + + status.setAttribute(DE.A_SOURCE, result); + statusDone(status); + + return status; + } + + private DataElement handleQueryFileOwner(DataElement subject, DataElement status) + { + File file = getFileFor(subject); + String result = null; + String os = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ + + if (os.startsWith("linux")){ //$NON-NLS-1$ + result = simpleShellCommand("stat -c%U", file); //$NON-NLS-1$ + } + else { + // in form " ..." + String ldStr = simpleShellCommand("ls -ld", file); //$NON-NLS-1$ + StringTokenizer tokenizer = new StringTokenizer(ldStr, " \t"); //$NON-NLS-1$ + tokenizer.nextToken(); + tokenizer.nextToken(); + result = tokenizer.nextToken(); // 3rd + } + + status.setAttribute(DE.A_SOURCE, result); + statusDone(status); + + return status; + } + + private DataElement handleSetFileOwner(DataElement subject, DataElement newOwner, DataElement status) + { + File file = getFileFor(subject); + String result = simpleShellCommand("chown " + newOwner.getName(), file); //$NON-NLS-1$ + + status.setAttribute(DE.A_SOURCE, result); + statusDone(status); + return status; + } + + private DataElement handleQueryFileGroupOwner(DataElement subject, DataElement status) + { + File file = getFileFor(subject); + String result = null; + String os = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ + + if (os.startsWith("linux")){ //$NON-NLS-1$ + result = simpleShellCommand("stat -c%G", file); //$NON-NLS-1$ + } + else { + // in form " ..." + String ldStr = simpleShellCommand("ls -ld", file); //$NON-NLS-1$ + + StringTokenizer tokenizer = new StringTokenizer(ldStr, " \t"); //$NON-NLS-1$ + tokenizer.nextToken(); + tokenizer.nextToken(); + tokenizer.nextToken(); + result = tokenizer.nextToken(); // 4rd + } + + status.setAttribute(DE.A_SOURCE, result); + statusDone(status); + + return status; + } + + private DataElement handleSetFileGroupOwner(DataElement subject, DataElement newGroup, DataElement status) + { + File file = getFileFor(subject); + String result = simpleShellCommand("chown :" + newGroup.getName(), file); //$NON-NLS-1$ + + status.setAttribute(DE.A_SOURCE, result); + statusDone(status); + return status; + } + + private String simpleShellCommand(String cmd) + { + String result = null; + String args[] = new String[3]; + args[0] = "sh"; //$NON-NLS-1$ + args[1] = "-c"; //$NON-NLS-1$ + args[2] = cmd; + + BufferedReader childReader = null; + try { + Process childProcess = Runtime.getRuntime().exec(args); + + childReader = new BufferedReader(new InputStreamReader(childProcess.getInputStream())); + + result = childReader.readLine().trim(); + childReader.close(); + } + catch (Exception e){ + try { + childReader.close(); + } + catch (IOException ex){} + } + return result; + + } + + private String simpleShellCommand(String cmd, File file) + { + String result = null; + String args[] = new String[3]; + args[0] = "sh"; //$NON-NLS-1$ + args[1] = "-c"; //$NON-NLS-1$ + args[2] = cmd + " " + PathUtility.enQuoteUnix(file.getAbsolutePath()); //$NON-NLS-1$ + + BufferedReader childReader = null; + try { + Process childProcess = Runtime.getRuntime().exec(args); + + childReader = new BufferedReader(new InputStreamReader(childProcess.getInputStream())); + + result = childReader.readLine().trim(); + childReader.close(); + } + catch (Exception e){ + try { + childReader.close(); + } + catch (IOException ex){} + } + return result; + + } } diff --git a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java index 431dfb843a3..775578e8fca 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java @@ -31,7 +31,8 @@ * Kevin Doyle (IBM) - [208778] [efs][api] RSEFileStore#getOutputStream() does not support EFS#APPEND * David McKnight (IBM) - [196624] dstore miner IDs should be String constants rather than dynamic lookup * David McKnight (IBM) - [209704] added supportsEncodingConversion() - * Xuan Chen (IBM) - [209827] Update DStore command implementation to enable cancelation of archive operations + * Xuan Chen (IBM) - [209827] Update DStore command implementation to enable cancelation of archive operations + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files ********************************************************************************/ package org.eclipse.rse.internal.services.dstore.files; @@ -74,12 +75,16 @@ import org.eclipse.rse.services.dstore.AbstractDStoreService; import org.eclipse.rse.services.dstore.util.DownloadListener; import org.eclipse.rse.services.dstore.util.FileSystemMessageUtil; import org.eclipse.rse.services.files.CodePageConverterManager; +import org.eclipse.rse.services.files.HostFilePermissions; +import org.eclipse.rse.services.files.IFileOwnerService; +import org.eclipse.rse.services.files.IFilePermissionsService; import org.eclipse.rse.services.files.IFileService; import org.eclipse.rse.services.files.IFileServiceCodePageConverter; import org.eclipse.rse.services.files.IHostFile; +import org.eclipse.rse.services.files.IHostFilePermissions; import org.eclipse.rse.services.files.RemoteFileSecurityException; -public class DStoreFileService extends AbstractDStoreService implements IFileService +public class DStoreFileService extends AbstractDStoreService implements IFileService, IFilePermissionsService, IFileOwnerService { protected org.eclipse.dstore.core.model.DataElement _uploadLogElement = null; @@ -1217,7 +1222,7 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer } else { - file = new DStoreHostFile(element); + file = new DStoreHostFile(element); } String path = file.getAbsolutePath(); _fileElementMap.put(path, element); @@ -2067,4 +2072,165 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer public boolean supportsEncodingConversion(){ return true; } + + + + + public boolean canGetFilePermissions(String remoteParent, String name) { + + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + DataElement queryCmd = getCommandDescriptor(remoteFile, IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS); + if (queryCmd != null){ + return true; + } + return false; + } + + public boolean canGetFileOwner(String remoteParent, String name) { + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + DataElement queryCmd = getCommandDescriptor(remoteFile, IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER); + if (queryCmd != null){ + return true; + } + return false; + } + + public boolean canSetFilePermissions(String remoteParent, String name) { + // for now just falling back to the same as get + return canGetFilePermissions(remoteParent, name); + } + + public boolean canSetFileOwner(String remoteParent, String name) { + // for now just falling back to the same as get + return canGetFileOwner(remoteParent, name); + } + + + public IHostFilePermissions getFilePermissions(String remoteParent, + String name, IProgressMonitor monitor) + throws SystemMessageException { + + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + DataElement status = dsStatusCommand(remoteFile, IUniversalDataStoreConstants.C_QUERY_FILE_PERMISSIONS, monitor); + if (status != null) { + int permissionsInt = 0; + String accessString = status.getSource(); // access string in octal + if (accessString != null && accessString.length() > 0) { + try + { + int accessInt = Integer.parseInt(accessString, 8); + permissionsInt = accessInt; // leave permissions in decimal + } + catch (Exception e){ + + } + HostFilePermissions permissions = new HostFilePermissions(permissionsInt); + return permissions; + } + } + + // nothing - server may not be up-to-date - missing permissions and owner support + return null; + } + + public void setFilePermissions(String remoteParent, String name, + IHostFilePermissions permissions, IProgressMonitor monitor) + throws SystemMessageException { + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + ArrayList args = new ArrayList(); + int bits = permissions.getPermissionBits(); + String permissionsInOctal = Integer.toOctalString(bits); // from decimal to octal + + DataElement newPermissionsElement = getDataStore().createObject(null, "permissions", permissionsInOctal); //$NON-NLS-1$ + args.add(newPermissionsElement); + + DataElement status = dsStatusCommand(remoteFile, args, IUniversalDataStoreConstants.C_SET_FILE_PERMISSIONS, monitor); + if (status != null) + { + // check status to make sure the file really changed + } + } + + + public String getFileUserOwner(String remoteParent, String name, + IProgressMonitor monitor) throws SystemMessageException { + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + DataElement status = dsStatusCommand(remoteFile, IUniversalDataStoreConstants.C_QUERY_FILE_USER_OWNER, monitor); + if (status != null) + { + String ownerString = status.getSource(); + if (ownerString != null && ownerString.length() > 0){ + return ownerString; + } + } + + // nothing - server may not be up-to-date - missing permissions and owner support + return null; + } + + public void setFileUserOwner(String remoteParent, String name, String newOwner, + IProgressMonitor monitor) throws SystemMessageException { + + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + ArrayList args = new ArrayList(); + DataElement newOwnerElement = getDataStore().createObject(null, "owner", newOwner); //$NON-NLS-1$ + args.add(newOwnerElement); + + DataElement status = dsStatusCommand(remoteFile, args, IUniversalDataStoreConstants.C_SET_FILE_USER_OWNER, monitor); + if (status != null) + { + // check status to make sure the file really changed + } + } + + public String getFileGroupOwner(String remoteParent, String name, + IProgressMonitor monitor) throws SystemMessageException { + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + DataElement status = dsStatusCommand(remoteFile, IUniversalDataStoreConstants.C_QUERY_FILE_GROUP_OWNER, monitor); + if (status != null) + { + String ownerString = status.getSource(); + if (ownerString != null && ownerString.length() > 0){ + return ownerString; + } + } + + // nothing - server may not be up-to-date - missing permissions and owner support + return null; + } + + public void setFileGroupOwner(String remoteParent, String name, String newOwner, + IProgressMonitor monitor) throws SystemMessageException { + + String remotePath = remoteParent + getSeparator(remoteParent) + name; + DataElement remoteFile = getElementFor(remotePath); + + ArrayList args = new ArrayList(); + DataElement newOwnerElement = getDataStore().createObject(null, "group", newOwner); //$NON-NLS-1$ + args.add(newOwnerElement); + + DataElement status = dsStatusCommand(remoteFile, args, IUniversalDataStoreConstants.C_SET_FILE_GROUP_OWNER, monitor); + if (status != null) + { + // check status to make sure the file really changed + } + } + + + + } \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/HostFilePermissions.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/HostFilePermissions.java new file mode 100644 index 00000000000..8629f21f28f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/HostFilePermissions.java @@ -0,0 +1,86 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are 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 + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files + ********************************************************************************/ +package org.eclipse.rse.services.files; + +/** + * Implementation of IHostFilePermissions. + * + */ +public class HostFilePermissions implements + IHostFilePermissions { + + private int _permissions = 0; + + /** + * Constructor that take the initial permissions as a bitmask + * @param initialPermissions the intial permissions bitmask + */ + public HostFilePermissions(int initialPermissions){ + _permissions = initialPermissions; + } + + public void setPermission(int permission, boolean value) { + if (value) + set(permission); + else + clear(permission); + } + + public boolean getPermission(int permission) { + return isSet(permission); + } + + public int getPermissionBits() { + return _permissions; + } + + public void setPermissionBits(int bits) { + _permissions = bits; + } + + public String toString(){ + return "" + _permissions; + } + + + private boolean isSet(long mask) { + return (_permissions & mask) != 0; + } + + private void set(int mask) { + _permissions |= mask; + } + + private void clear(int mask) { + _permissions &= ~mask; + } + + /** + * return permissions in rwxrwxrwx form + */ + public String toUserString(){ + StringBuffer buf = new StringBuffer(); + + buf.append(getPermission(IHostFilePermissions.PERM_USER_READ) ? 'r' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_USER_WRITE) ? 'w' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_USER_EXECUTE) ? 'x' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_GROUP_READ) ? 'r' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_GROUP_WRITE) ? 'w' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_GROUP_EXECUTE) ? 'x' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_OTHER_READ) ? 'r' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_OTHER_WRITE) ? 'w' : '-'); + buf.append(getPermission(IHostFilePermissions.PERM_OTHER_EXECUTE) ? 'x' : '-'); + return buf.toString(); + } +} diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileOwnerService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileOwnerService.java new file mode 100644 index 00000000000..a68431c6559 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileOwnerService.java @@ -0,0 +1,83 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are 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 + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files + ********************************************************************************/ +package org.eclipse.rse.services.files; + +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; + +/** + * Service used to get and set the owner of a file. + */ +public interface IFileOwnerService { + /** + * @param remoteParent + * @param name + * @param monitor the monitor for this potentially long running operation + * @return the host file owner + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the RemoteFileException family. + */ + public String getFileUserOwner(String remoteParent, String name, IProgressMonitor monitor) throws SystemMessageException; + + /** + * @param remoteParent + * @param name + * @param monitor the monitor for this potentially long running operation + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the RemoteFileException family. + */ + public void setFileUserOwner(String remoteParent, String name, String newOwner, IProgressMonitor monitor) throws SystemMessageException; + + /** + * @param remoteParent + * @param name + * @param monitor the monitor for this potentially long running operation + * @return the host file owner + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the RemoteFileException family. + */ + public String getFileGroupOwner(String remoteParent, String name, IProgressMonitor monitor) throws SystemMessageException; + + /** + * @param remoteParent + * @param name + * @param monitor the monitor for this potentially long running operation + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the RemoteFileException family. + */ + public void setFileGroupOwner(String remoteParent, String name, String newGroupOwner, IProgressMonitor monitor) throws SystemMessageException; + + + + /** + * Indicates whether the file owner can be retrieved for the specified file + * In some cases the service will need to determine whether it supports ownership + * depending on the current server. + * + * @param remoteParent the + * @param name + * @return whether the file owner can be retrieved + */ + public boolean canGetFileOwner(String remoteParent, String name); + + /** + * Indicates whether the file owner can be set for the specified file + * + * @param remoteParent the + * @param name + * @return whether the file owner can be set + */ + public boolean canSetFileOwner(String remoteParent, String name); +} diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFilePermissionsService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFilePermissionsService.java new file mode 100644 index 00000000000..ff50935b523 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFilePermissionsService.java @@ -0,0 +1,64 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are 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 + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files + ********************************************************************************/ +package org.eclipse.rse.services.files; + +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; + +/** + * Service used to get and set the permissions of a file. + */ +public interface IFilePermissionsService { + + /** + * @param remoteParent + * @param name + * @param monitor the monitor for this potentially long running operation + * @return the host file permissions + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the RemoteFileException family. + */ + public IHostFilePermissions getFilePermissions(String remoteParent, String name, IProgressMonitor monitor) throws SystemMessageException; + + /** + * @param remoteParent + * @param name + * @param permissions the new permissions for this file + * @param monitor the monitor for this potentially long running operation + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the RemoteFileException family. + */ + public void setFilePermissions(String remoteParent, String name, IHostFilePermissions permissions, IProgressMonitor monitor) throws SystemMessageException; + + /** + * Indicates whether the file permissions can be retrieved for the specified file. + * In some cases the service will need to determine whether it supports permissions + * depending on the current server. + * + * @param remoteParent + * @param name + * @return whether the file permissions can be retrieved + */ + public boolean canGetFilePermissions(String remoteParent, String name); + + /** + * Indicates whether the file permissions can be set for the specified file + * + * @param remoteParent + * @param name + * @return whether the file permissions can be set + */ + public boolean canSetFilePermissions(String remoteParent, String name); +} diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IHostFilePermissions.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IHostFilePermissions.java new file mode 100644 index 00000000000..8955ce3f040 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IHostFilePermissions.java @@ -0,0 +1,122 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are 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 + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files + ********************************************************************************/ +package org.eclipse.rse.services.files; + + +public interface IHostFilePermissions { + + /** + * Permission constant indicating that + * the user can read this file + */ + public static final int PERM_USER_READ = 1 << 8; + + /** + * Permission constant indicating that + * the user can write to this file + */ + public static final int PERM_USER_WRITE = 1 << 7; + + /** + * Permission constant indicating that + * the user can execute this file + */ + public static final int PERM_USER_EXECUTE = 1 << 6; + + /** + * Permission constant indicating that + * the group can read this file + */ + public static final int PERM_GROUP_READ = 1 << 5; + + /** + * Permission constant indicating that + * the group can write to this file + * + */ + public static final int PERM_GROUP_WRITE = 1 << 4; + + /** + * Permission constant indicating that + * the group can execute this file + * + */ + public static final int PERM_GROUP_EXECUTE = 1 << 3; + + /** + * Permission constant indicating that + * other users can read this file + * + */ + public static final int PERM_OTHER_READ = 1 << 2; + + /** + * Permission constant indicating that + * other users can write to this file + * + */ + public static final int PERM_OTHER_WRITE = 1 << 1; + + /** + * Permission constant indicating that + * other users can execute to this file + * + */ + public static final int PERM_OTHER_EXECUTE = 1 << 0; + + + // support masks + public static final int PERM_ANY_READ = PERM_USER_READ | PERM_GROUP_READ | PERM_OTHER_READ; + public static final int PERM_ANY_WRITE = PERM_USER_WRITE | PERM_GROUP_WRITE | PERM_OTHER_WRITE; + public static final int PERM_ANY_EXECUTE = PERM_USER_EXECUTE | PERM_GROUP_EXECUTE | PERM_OTHER_EXECUTE; + + /** + * Set or reset all the permission bits from the given bitmask. + * + * @param bitmask the permission(s) bits to modify + * @param value whether to turn on off of the permission(s) + * + * Example: setPermission(PERM_USER_WRITE | PERM_GROUP_WRITE, true); + */ + public void setPermission(int bitmask, boolean value); + + /** + * Test if any of the permission bits from the bitmask are set. + * + * @param bitmask the permission(s) to check for + * @return true if one of the permission bits is set + * + * Example: getPermission(PERM_USER_WRITE | PERM_GROUP_WRITE) + */ + public boolean getPermission(int bitmask); + + /** + * Get the set of permission bits. + * + * @return set of permission bits + */ + public int getPermissionBits(); + + /** + * Set the permission bits + * @param bits the set of permission bits + */ + public void setPermissionBits(int bits); + + + /** + * return permissions in rwxrwxrwx form + */ + public String toUserString(); +} diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.core/plugin.xml b/rse/plugins/org.eclipse.rse.subsystems.files.core/plugin.xml index b4333e9d4dc..2f792791c3e 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.core/plugin.xml +++ b/rse/plugins/org.eclipse.rse.subsystems.files.core/plugin.xml @@ -46,4 +46,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/internal/subsystems/files/core/RemoteFilePermissionsAdapterFactory.java b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/internal/subsystems/files/core/RemoteFilePermissionsAdapterFactory.java new file mode 100644 index 00000000000..56ebd0b9633 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/internal/subsystems/files/core/RemoteFilePermissionsAdapterFactory.java @@ -0,0 +1,65 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are 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 + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files + ********************************************************************************/ +package org.eclipse.rse.internal.subsystems.files.core; + +import org.eclipse.rse.services.files.IFileOwnerService; +import org.eclipse.rse.services.files.IFilePermissionsService; +import org.eclipse.rse.services.files.IFileService; +import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.ui.view.AbstractSystemRemoteAdapterFactory; + +public class RemoteFilePermissionsAdapterFactory extends + AbstractSystemRemoteAdapterFactory { + + + + public Object getAdapter(Object adaptableObject, Class adapterType) { + + IFileService fileService = null; + if (adaptableObject instanceof IFileService){ + fileService = (IFileService)adaptableObject; + } + else if (adaptableObject instanceof IRemoteFile){ + FileServiceSubSystem ss = (FileServiceSubSystem)((IRemoteFile)adaptableObject).getParentRemoteFileSubSystem(); + if (ss != null){ + fileService = ss.getFileService(); + } + } + + if (fileService != null){ + if (adapterType == IFilePermissionsService.class){ + if (fileService instanceof IFilePermissionsService){ + return fileService; + } + } + else if (adapterType == IFileOwnerService.class){ + if (fileService instanceof IFileOwnerService){ + return fileService; + } + } + + } + + return null; + } + + /** + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() + */ + public Class[] getAdapterList() + { + return new Class[] {IFilePermissionsService.class, IFileOwnerService.class}; + } +} diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFile.java b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFile.java index 9b92656ee0b..c5a65cd4039 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFile.java +++ b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFile.java @@ -12,7 +12,7 @@ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * * Contributors: - * {Name} (company) - description of contribution. + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files *******************************************************************************/ package org.eclipse.rse.subsystems.files.core.subsystems; @@ -23,6 +23,7 @@ import org.eclipse.rse.core.model.IHost; import org.eclipse.rse.core.subsystems.IRemoteContainer; import org.eclipse.rse.core.subsystems.IRemotePropertyHolder; import org.eclipse.rse.services.files.IHostFile; +import org.eclipse.rse.services.files.IHostFilePermissions; import org.eclipse.rse.subsystems.files.core.model.RemoteFileFilterString; /** @@ -334,4 +335,23 @@ public interface IRemoteFile extends IRemoteContainer, IRemotePropertyHolder, IS * @since 2.0 */ public String getEncoding(); + + /** + * Returns the permissions for this file if they exist + * @return the permissions + */ + public IHostFilePermissions getPermissions(); + + /** + * Returns the owner for this file if it exists + * @return the owner + */ + public String getOwner(); + + /** + * Returns the group for this file if it exists + * @return the group + */ + public String getGroup(); + } diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/RemoteFile.java b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/RemoteFile.java index 75669df3ca6..4fbe9dbcaca 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/RemoteFile.java +++ b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/RemoteFile.java @@ -16,6 +16,7 @@ * David McKnight (IBM) - [173518] [refresh] Read only changes are not shown in RSE until the parent folder is refreshed * David McKnight (IBM) - [186363] get rid of obsolete calls to ISubSystem.connect() * David McKnight (IBM) - [209660] use parent encoding as default, rather than system encoding + * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files *******************************************************************************/ package org.eclipse.rse.subsystems.files.core.subsystems; @@ -43,6 +44,7 @@ import org.eclipse.rse.core.subsystems.RemoteChildrenContentsType; import org.eclipse.rse.services.clientserver.StringComparePatternMatcher; import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; +import org.eclipse.rse.services.files.IHostFilePermissions; import org.eclipse.rse.subsystems.files.core.model.RemoteFileFilterString; import org.eclipse.rse.subsystems.files.core.model.SystemFileTransferModeRegistry; import org.eclipse.rse.ui.SystemBasePlugin; @@ -75,7 +77,8 @@ public abstract class RemoteFile implements IRemoteFile, IAdaptable, Comparable { - protected IRemoteFileContext _context; + + protected IRemoteFileContext _context; protected String fullyQualifiedName; protected String _label; @@ -96,6 +99,11 @@ public abstract class RemoteFile implements IRemoteFile, IAdaptable, Comparable // properties protected HashMap properties = new HashMap(); protected HashMap propertyStates = new HashMap(); + + // permissions + protected IHostFilePermissions _permissions; + protected String _owner; + protected String _group; /** * Constructor that takes a context object containing important information. @@ -899,6 +907,9 @@ public abstract class RemoteFile implements IRemoteFile, IAdaptable, Comparable public void markStale(boolean isStale, boolean clearCache) { _isStale = isStale; + _owner = null; + _group = null; + _permissions = null; if (isStale && clearCache) { @@ -1196,4 +1207,32 @@ public abstract class RemoteFile implements IRemoteFile, IAdaptable, Comparable public void setEncoding(String encoding) { RemoteFileEncodingManager.getInstance().setEncoding(getHostName(), getAbsolutePath(), encoding); } + + public void setGroup(String group) { + _group = group; + } + + public void setOwner(String owner) { + _owner = owner; + } + + public void setPermissions(IHostFilePermissions permissions) { + _permissions = permissions; + } + + + public String getGroup() { + return _group; + } + + + public String getOwner() { + return _owner; + } + + + public IHostFilePermissions getPermissions() { + return _permissions; + } + }