From 28e99e8e3ad3174edb8116d1990ebc445eb6dcc4 Mon Sep 17 00:00:00 2001 From: David McKnight Date: Sat, 24 Nov 2007 00:36:27 +0000 Subject: [PATCH] [209704] [api] Ability to override default encoding conversion needed. --- .../dstore/files/DStoreFileService.java | 78 ++--------- .../org.eclipse.rse.services/plugin.xml | 3 +- .../schema/codePageConverters.exsd | 121 ++++++++++++++++++ .../rse/internal/services/Activator.java | 91 +++++++++++++ .../services/files/AbstractFileService.java | 63 --------- .../DefaultFileServiceCodePageConverter.java | 11 +- .../files/IFileServiceCodePageConverter.java | 10 +- 7 files changed, 241 insertions(+), 136 deletions(-) create mode 100644 rse/plugins/org.eclipse.rse.services/schema/codePageConverters.exsd 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 40cfc884072..cdd722d261b 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 @@ -45,15 +45,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Vector; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; import org.eclipse.dstore.core.model.DE; import org.eclipse.dstore.core.model.DataElement; import org.eclipse.dstore.core.model.DataStore; @@ -63,6 +56,7 @@ import org.eclipse.dstore.core.model.IDataStoreProvider; import org.eclipse.rse.dstore.universal.miners.IUniversalDataStoreConstants; import org.eclipse.rse.dstore.universal.miners.UniversalByteStreamHandler; import org.eclipse.rse.dstore.universal.miners.UniversalFileSystemMiner; +import org.eclipse.rse.internal.services.Activator; import org.eclipse.rse.internal.services.dstore.ServiceResources; import org.eclipse.rse.services.clientserver.FileTypeMatcher; import org.eclipse.rse.services.clientserver.IMatcher; @@ -77,7 +71,6 @@ import org.eclipse.rse.services.clientserver.messages.SystemMessageException; 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.DefaultFileServiceCodePageConverter; import org.eclipse.rse.services.files.IFileService; import org.eclipse.rse.services.files.IFileServiceCodePageConverter; import org.eclipse.rse.services.files.IHostFile; @@ -94,8 +87,7 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer private int _bufferDownloadSize = IUniversalDataStoreConstants.BUFFER_SIZE; protected ISystemFileTypes _fileTypeRegistry; private String remoteEncoding; - private IFileServiceCodePageConverter _defaultCodePageConverter; - protected Vector _codePageConverters; + protected boolean unixStyle = false; @@ -435,59 +427,6 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer return true; } - protected IFileServiceCodePageConverter getDefaultCodePageConverter() - { - if (_defaultCodePageConverter == null){ - _defaultCodePageConverter = new DefaultFileServiceCodePageConverter(); - } - return _defaultCodePageConverter; - } - - /** - * Retrieves the first codepage converter provided via the codePageConverter extension point for the specified - * encoding - * @param serverEncoding The server encoding for which to retrieve a code page converter - * @return A code page converter for the specified encoding, or null if no converter was found for that encoding. - */ - protected IFileServiceCodePageConverter getCodePageConverter(String serverEncoding) { - if (_codePageConverters == null) { - // retrieve all extension points - IExtensionRegistry registry = Platform.getExtensionRegistry(); - IExtensionPoint ep = registry.getExtensionPoint("org.eclipse.rse.services", "codePageConverter"); //$NON-NLS-1$ - if (ep != null){ - IExtension[] extensions = ep.getExtensions(); - _codePageConverters = new Vector(); - for (int i = 0; i < extensions.length; i++) { - IExtension extension = extensions[i]; - IConfigurationElement[] configElements = extension.getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - IConfigurationElement element = configElements[j]; - if (element.getName().equalsIgnoreCase("codePageConverter")) { - try { - Object codePageConverter = element.createExecutableExtension("class"); - if (codePageConverter!=null && codePageConverter instanceof IFileServiceCodePageConverter) - // only save extension point which implement the correct interface - _codePageConverters.add(codePageConverter); - } catch (CoreException e) { - //shouldn't get here.... - } - } - } - } - } - } - if (_codePageConverters != null) - { - //scan through the available converters and return the first valid one for the specified encoding for this - // subsystem implementation - for (int i=0; i<_codePageConverters.size(); i++) { - IFileServiceCodePageConverter codePageConverter = (IFileServiceCodePageConverter)_codePageConverters.elementAt(i); - if (codePageConverter.isServerEncodingSupported(serverEncoding, this)) - return codePageConverter; - } - } - return null; - } public boolean upload(File file, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding, IProgressMonitor monitor) @@ -549,9 +488,9 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer int localLineSepLength = localLineSep.length(); - IFileServiceCodePageConverter codePageConverter = getCodePageConverter(hostEncoding); + IFileServiceCodePageConverter codePageConverter = Activator.getCodePageConverter(hostEncoding, this); if (codePageConverter == null) { - codePageConverter = getDefaultCodePageConverter(); + codePageConverter = Activator.getDefaultCodePageConverter(); } // upload bytes while available @@ -849,9 +788,10 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer { if (!isBinary){ // do standard conversion if this is text! String localEncoding = System.getProperty("file.encoding"); - IFileServiceCodePageConverter codePageConverter = getCodePageConverter(encoding); + + IFileServiceCodePageConverter codePageConverter = Activator.getCodePageConverter(encoding, this); if (codePageConverter == null) { - codePageConverter = getDefaultCodePageConverter(); + codePageConverter = Activator.getDefaultCodePageConverter(); } codePageConverter.convertFileFromRemoteEncoding(localFile, encoding, localEncoding, this); } @@ -1080,9 +1020,9 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer // do standard conversion if this is text! if (!isBinaries[i]){ // do standard conversion if this is text! String localEncoding = System.getProperty("file.encoding"); - IFileServiceCodePageConverter codePageConverter = getCodePageConverter(hostEncodings[i]); + IFileServiceCodePageConverter codePageConverter = Activator.getCodePageConverter(hostEncodings[i], this); if (codePageConverter == null) { - codePageConverter = getDefaultCodePageConverter(); + codePageConverter = Activator.getDefaultCodePageConverter(); } codePageConverter.convertFileFromRemoteEncoding(localFile, hostEncodings[i], localEncoding, this); } diff --git a/rse/plugins/org.eclipse.rse.services/plugin.xml b/rse/plugins/org.eclipse.rse.services/plugin.xml index dc113d492b7..52d1ae933c3 100644 --- a/rse/plugins/org.eclipse.rse.services/plugin.xml +++ b/rse/plugins/org.eclipse.rse.services/plugin.xml @@ -2,5 +2,6 @@ - + + diff --git a/rse/plugins/org.eclipse.rse.services/schema/codePageConverters.exsd b/rse/plugins/org.eclipse.rse.services/schema/codePageConverters.exsd new file mode 100644 index 00000000000..60f8a2c4b1d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/schema/codePageConverters.exsd @@ -0,0 +1,121 @@ + + + + + + + + + This extension point allows the default codepage conversion for files transfered via the file services to be provided by the extension point. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RSE 3.0 + + + + + + + + + The following is an example of this extension point's usage: + +<p> +<pre> + <extension point="org.eclipse.rse.services.codePageConverters"> + <codePageConverter + id="org.eclipse.rse.services.files.defaultCodePageConverter" + name="Default Code Page Converter" + class="org.eclipse.rse.files.DefaultFileServiceCodePageConverter"> + </codePageConverter> + </extension> +</pre> +</p> + + + + + + + + + Plug-ins that want to extend this extension point must implement <samp>org.eclipse.rse.services.files.IFileServiceCodePageConverter</samp> interface. + + + + + + + + + Users of this extension point must implement the interface + org.eclipse.rse.services.files.IFileServiceCodePageConverter + + + + + + + + + Copyright (c) 2002, 2006, 2007 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 + +Contributors: +IBM Corporation - initial API and implementation + + + + diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/Activator.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/Activator.java index f7198db3bdc..af0cbb2f1fd 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/Activator.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/Activator.java @@ -12,6 +12,7 @@ * * Contributors: * Martin Oberhuber (Wind River) - Moved from org.eclipse.rse.services + * David McKnight (IBM) - [209704] [api] Ability to override default encoding conversion needed. ********************************************************************************/ package org.eclipse.rse.internal.services; @@ -19,8 +20,12 @@ package org.eclipse.rse.internal.services; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Vector; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IStatus; @@ -31,6 +36,9 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager; +import org.eclipse.rse.services.files.DefaultFileServiceCodePageConverter; +import org.eclipse.rse.services.files.IFileService; +import org.eclipse.rse.services.files.IFileServiceCodePageConverter; /** * The main plugin class to be used in the desktop. @@ -40,6 +48,9 @@ public class Activator extends Plugin { //The shared instance. private static Activator plugin; + private static IFileServiceCodePageConverter _defaultCodePageConverter; + protected static Vector _codePageConverters; + /** * The constructor. */ @@ -54,6 +65,7 @@ public class Activator extends Plugin { public void start(BundleContext context) throws Exception { super.start(context); registerArchiveHandlers(); + registerCodePageConverters(); } /* @@ -113,6 +125,85 @@ public class Activator extends Plugin { } } + + + + private void registerCodePageConverters() + { + if (_codePageConverters == null) { + // retrieve all extension points + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint ep = registry.getExtensionPoint("org.eclipse.rse.services", "codePageConverters"); //$NON-NLS-1$ + if (ep != null){ + IExtension[] extensions = ep.getExtensions(); + _codePageConverters = new Vector(); + for (int i = 0; i < extensions.length; i++) { + IExtension extension = extensions[i]; + IConfigurationElement[] configElements = extension.getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + IConfigurationElement element = configElements[j]; + if (element.getName().equalsIgnoreCase("codePageConverter")) { + try { + Object codePageConverter = element.createExecutableExtension("class"); + if (codePageConverter!=null && codePageConverter instanceof IFileServiceCodePageConverter){ + // only save extension point which implement the correct interface + _codePageConverters.add(codePageConverter); + } + } + catch (CoreException e) { + //shouldn't get here.... + e.printStackTrace(); + } + } + } + } + } + } + + if (_defaultCodePageConverter == null){ + _defaultCodePageConverter = new DefaultFileServiceCodePageConverter(); + } + } + + public static IFileServiceCodePageConverter getDefaultCodePageConverter() + { + return _defaultCodePageConverter; + } + + /** + * Retrieves the first codepage converter provided via the codePageConverter extension point for the specified + * encoding + * @param serverEncoding The server encoding for which to retrieve a code page converter + * @return A code page converter for the specified encoding, or null if no converter was found for that encoding. + */ + public static IFileServiceCodePageConverter getCodePageConverter(String serverEncoding, IFileService fileService) { + + IFileServiceCodePageConverter matchingCodePageConverter = null; + if (_codePageConverters != null) + { + + //scan through the available converters and return the first valid one for the specified encoding for this + // subsystem implementation + for (int i=0; i<_codePageConverters.size(); i++) { + IFileServiceCodePageConverter codePageConverter = (IFileServiceCodePageConverter)_codePageConverters.elementAt(i); + if (codePageConverter.isServerEncodingSupported(serverEncoding, fileService)) + { + if (matchingCodePageConverter != null){ + int matchingPriority = matchingCodePageConverter.getPriority(serverEncoding, fileService); + int newPriority = codePageConverter.getPriority(serverEncoding, fileService); + if (newPriority < matchingPriority){ + matchingCodePageConverter = codePageConverter; + } + } + else { + matchingCodePageConverter = codePageConverter; + } + } + } + } + return matchingCodePageConverter; + } + /** * Logs an throwable to the log for this plugin. * @param t the Throwable to be logged. diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java index ba94a51f8d8..c5602e69742 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java @@ -28,15 +28,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import java.util.Vector; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; import org.eclipse.rse.services.clientserver.messages.SystemMessage; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; @@ -44,8 +37,6 @@ import org.eclipse.rse.services.clientserver.messages.SystemMessageException; public abstract class AbstractFileService implements IFileService { - protected Vector _codePageConverters; - private IFileServiceCodePageConverter _defaultCodePageConverter; protected abstract IHostFile[] internalFetch(String parentPath, String fileFilter, int fileType, IProgressMonitor monitor) throws SystemMessageException; @@ -219,58 +210,4 @@ public abstract class AbstractFileService implements IFileService public OutputStream getOutputStream(String remoteParent, String remoteFile, boolean isBinary, IProgressMonitor monitor) throws SystemMessageException { return null; } - - protected IFileServiceCodePageConverter getDefaultCodePageConverter() - { - if (_defaultCodePageConverter == null){ - _defaultCodePageConverter = new DefaultFileServiceCodePageConverter(); - } - return _defaultCodePageConverter; - } - - /** - * Retrieves the first codepage converter provided via the codePageConverter extension point for the specified - * encoding - * @param serverEncoding The server encoding for which to retrieve a code page converter - * @return A code page converter for the specified encoding, or null if no converter was found for that encoding. - */ - protected IFileServiceCodePageConverter getCodePageConverter(String serverEncoding) { - if (_codePageConverters == null) { - // retrieve all extension points - IExtensionRegistry registry = Platform.getExtensionRegistry(); - IExtensionPoint ep = registry.getExtensionPoint("org.eclipse.rse.services", "codePageConverter"); //$NON-NLS-1$ - if (ep != null){ - IExtension[] extensions = ep.getExtensions(); - _codePageConverters = new Vector(); - for (int i = 0; i < extensions.length; i++) { - IExtension extension = extensions[i]; - IConfigurationElement[] configElements = extension.getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - IConfigurationElement element = configElements[j]; - if (element.getName().equalsIgnoreCase("codePageConverter")) { - try { - Object codePageConverter = element.createExecutableExtension("class"); - if (codePageConverter!=null && codePageConverter instanceof IFileServiceCodePageConverter) - // only save extension point which implement the correct interface - _codePageConverters.add(codePageConverter); - } catch (CoreException e) { - //shouldn't get here.... - } - } - } - } - } - } - if (_codePageConverters != null) - { - //scan through the available converters and return the first valid one for the specified encoding for this - // subsystem implementation - for (int i=0; i<_codePageConverters.size(); i++) { - IFileServiceCodePageConverter codePageConverter = (IFileServiceCodePageConverter)_codePageConverters.elementAt(i); - if (codePageConverter.isServerEncodingSupported(serverEncoding, this)) - return codePageConverter; - } - } - return null; - } } \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/DefaultFileServiceCodePageConverter.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/DefaultFileServiceCodePageConverter.java index ae98d1ca218..2821f3d7627 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/DefaultFileServiceCodePageConverter.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/DefaultFileServiceCodePageConverter.java @@ -50,7 +50,8 @@ public class DefaultFileServiceCodePageConverter implements byte[] localBuffer = new String(buffer, 0, bytesRead, remoteEncoding).getBytes(localEncoding); FileOutputStream outStream = new FileOutputStream(file); - outStream.write(localBuffer, 0, localBuffer.length); + outStream.write(localBuffer, 0, localBuffer.length); + outStream.close(); } catch (Exception e) { @@ -62,5 +63,13 @@ public class DefaultFileServiceCodePageConverter implements IFileService fs) { return true; } + + /** + * to make another converter take precedence over this, supply a + * code page converter returning a lower number (i.e. higher priority) + */ + public int getPriority(String remoteEString, IFileService fs){ + return 1000; + } } diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileServiceCodePageConverter.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileServiceCodePageConverter.java index 458a265d7f6..bde87546a94 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileServiceCodePageConverter.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileServiceCodePageConverter.java @@ -42,7 +42,7 @@ public interface IFileServiceCodePageConverter { * @param fs The file service to apply conversion to. * Can be used to determine implementation specific settings to the converter */ - public void convertFileFromRemoteEncoding(File file, String remoteEncoding, String localEncoding, IFileService uss); + public void convertFileFromRemoteEncoding(File file, String remoteEncoding, String localEncoding, IFileService fs); /** * Indicates whether or not the specified server encoding and subsystem implementation is supported by this code page converter @@ -51,6 +51,12 @@ public interface IFileServiceCodePageConverter { * Can be used to determine implementation specific settings to the converter * @return True if this code page converter can convert the specified encoding, false otherwise */ - public boolean isServerEncodingSupported(String remoteEncoding, IFileService uss); + public boolean isServerEncodingSupported(String remoteEncoding, IFileService fs); + /** + * Indicates the priority of this code page converter if more than one code page converter + * handle a particular encoding. The lower the number, the higher the priority. + * @return priority + */ + public int getPriority(String remoteEncoding, IFileService fs); }