| /******************************************************************************* |
| * Copyright (c) 2007, 2008 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 |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.security.storage; |
| |
| import java.io.*; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import org.eclipse.equinox.internal.security.auth.AuthPlugin; |
| import org.eclipse.equinox.internal.security.auth.nls.SecAuthMessages; |
| import org.eclipse.osgi.util.NLS; |
| |
| /** |
| * PLEASE READ BEFORE CHANGING THIS FILE |
| * |
| * At present most of the methods expect only file URLs. The API methods |
| * take URLs for possible future expansion, and there is some code below |
| * that would work with some other URL types, but the only supported URL |
| * types at this time are file URLs. Also note that URL paths should not |
| * be encoded (spaces should be spaces, not "%x20"). |
| * |
| * On encoding: Java documentation recommends using File.toURI().toURL(). |
| * However, in this process non-alphanumeric characters (including spaces) |
| * get encoded and can not be used with the rest of Eclipse methods that |
| * expect non-encoded strings. |
| */ |
| public class StorageUtils { |
| |
| /** |
| * Characters encoding used by the secure storage. |
| */ |
| final public static String CHAR_ENCODING = "UTF-8"; //$NON-NLS-1$ |
| |
| /** |
| * Default name of the storage file |
| */ |
| final private static String propertiesFileName = ".eclipse/org.eclipse.equinox.security/secure_storage"; //$NON-NLS-1$ |
| |
| static private boolean firstCharsetException = true; |
| |
| /** |
| * Default locations: |
| * 1) user.home |
| * 2) Eclipse config location |
| */ |
| static public URL getDefaultLocation() throws IOException { |
| String userHome = System.getProperty("user.home"); //$NON-NLS-1$ |
| if (userHome != null) { |
| File file = new File(userHome, propertiesFileName); |
| // NOTE: Don't use File.toURI().toURL() as it will escape space characters and such. |
| // The escaped sequence will fail later when we try to open a stream on it. |
| return file.toURL(); |
| } |
| // use install location |
| URL installLocation = AuthPlugin.getDefault().getConfigURL(); |
| if (installLocation != null && isFile(installLocation)) { |
| File file = new File(installLocation.getPath(), propertiesFileName); |
| // NOTE: Same thing about toURI() as above |
| return file.toURL(); |
| } |
| // practically, we never should reach this point but just in case: |
| throw new IOException(SecAuthMessages.loginNoDefaultLocation); |
| } |
| |
| static public OutputStream getOutputStream(URL url) throws IOException { |
| if (isFile(url)) { |
| File file = new File(url.getPath()); |
| if (!file.exists()) { |
| File parent = file.getParentFile(); |
| if (parent != null && !parent.exists()) |
| parent.mkdirs(); |
| } |
| return new FileOutputStream(file); |
| } |
| // note that code below does not work for File URLs - "by design" Java |
| // does not support creating output streams on file URLs. Code below should work |
| // for HTTP URLs; no idea as to the other types of URLs |
| URLConnection connection = url.openConnection(); |
| connection.setDoOutput(true); |
| return connection.getOutputStream(); |
| } |
| |
| static public InputStream getInputStream(URL url) throws IOException { |
| if (url == null) |
| return null; |
| try { |
| return url.openStream(); |
| } catch (FileNotFoundException e) { |
| return null; // this is all right, means new file |
| } |
| } |
| |
| static public boolean delete(URL url) { |
| if (isFile(url)) { |
| File file = new File(url.getPath()); |
| return file.delete(); |
| } |
| return false; |
| } |
| |
| static public boolean exists(URL url) { |
| if (isFile(url)) { |
| File file = new File(url.getPath()); |
| return file.exists(); |
| } |
| return true; |
| } |
| |
| static public boolean isFile(URL url) { |
| return ("file".equals(url.getProtocol())); //$NON-NLS-1$ |
| } |
| |
| /** |
| * The {@link String#getBytes()} truncates non-ASCII chars. As a result |
| * new String(string.getBytes()) is not the same as the original string. Moreover, |
| * the default Java encoding can be changed via system variables or startup conditions. |
| */ |
| static public byte[] getBytes(String string) { |
| if (string == null) |
| return null; |
| try { |
| return string.getBytes(CHAR_ENCODING); |
| } catch (UnsupportedEncodingException e) { |
| if (firstCharsetException) { // log error once per session |
| String msg = NLS.bind(SecAuthMessages.unsupoprtedCharEncoding, StorageUtils.CHAR_ENCODING); |
| AuthPlugin.getDefault().logMessage(msg); |
| firstCharsetException = false; |
| } |
| return string.getBytes(); |
| } |
| } |
| |
| /** |
| * The new String(byte[]) method uses default system encoding which |
| * might not properly process non-ASCII characters. |
| * |
| * Pairing {@link #getBytes(String)} and {@link #getString(byte[])} methods allows round trip |
| * of non-ASCII characters. |
| */ |
| static public String getString(byte[] bytes) { |
| if (bytes == null) |
| return null; |
| try { |
| return new String(bytes, CHAR_ENCODING); |
| } catch (UnsupportedEncodingException e) { |
| if (firstCharsetException) { // log error once per session |
| String msg = NLS.bind(SecAuthMessages.unsupoprtedCharEncoding, StorageUtils.CHAR_ENCODING); |
| AuthPlugin.getDefault().logMessage(msg); |
| firstCharsetException = false; |
| } |
| return new String(bytes); |
| } |
| } |
| |
| } |