--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/gcfprotocols/file/javasrc/com/nokia/mj/impl/file/FileConnectionImpl.java Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,1028 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.mj.impl.file;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.microedition.io.Connector;
+import javax.microedition.io.file.ConnectionClosedException;
+import javax.microedition.io.file.FileConnection;
+import javax.microedition.io.file.IllegalModeException;
+
+import com.nokia.mj.impl.fileutils.FileUtility;
+import com.nokia.mj.impl.fileutils.FileUTF8Handler;
+import com.nokia.mj.impl.rt.support.ApplicationUtils;
+import com.nokia.mj.impl.rt.support.Finalizer;
+import com.nokia.mj.impl.rt.support.Jvm;
+
+/**
+ * FileConnectionImpl implements all the methods of
+ * javax.microedition.io.file.FileConnection;
+ */
+public final class FileConnectionImpl implements FileConnection
+{
+ static
+ {
+ try
+ {
+ Jvm.loadSystemLibrary("javafile");
+ }
+ catch (Exception e)
+ {
+ FileLogger.ELog("Unable to load javafile native library");
+ }
+ }
+
+ private FileUtility iFileUtility;
+
+ private Finalizer iFinalizer;
+
+ private boolean iIsOpen;
+
+ private int iMode;
+
+ private String iInitialUrl;
+
+ private String FILE_LOCALHOST = "//localhost/";
+
+ private String FILE_SIMPLE = "///";
+
+ private FileConnectionURL iFileConnectionUrl;
+
+ public FileConnectionImpl(String aName, int aMode, boolean aTimeouts)
+ throws IOException
+ {
+ iInitialUrl = "file:" + aName;
+
+ String decodedUrl = FileUTF8Handler.decode(iInitialUrl);
+ decodedUrl = decodedUrl.replace('|', ':');
+
+ // Validate File URL first.
+ FileConnectionURL.checkFileUrlValidity(decodedUrl);
+ String actual = FileUrlValidator.validateFileUrl(decodedUrl);
+
+ if (iInitialUrl.startsWith("file:" + FILE_SIMPLE))
+ {
+ // Construct a FileConnectionURL type if the validation passes.
+ iFileConnectionUrl = new FileConnectionURL(iInitialUrl, "file:///"
+ + actual, false);
+ }
+ else
+ {
+ // Construct a FileConnectionURL type if the validation passes.
+ iFileConnectionUrl = new FileConnectionURL(iInitialUrl,
+ "file://localhost/" + actual, false);
+ }
+
+ // Check access.
+ checkAccess(actual, aMode, true);
+
+ // Go ahead to prompt the user
+ checkSecurityPermission(actual, aMode);
+
+ FileLogger.Log("FileConnectionImpl: Creating FileUtility With: "
+ + actual);
+
+ // FileUtility can handle multiple "//" in the path.
+ // Need to check it ourselves.
+ if (actual.indexOf("//") != -1)
+ {
+ throw new IllegalArgumentException("Invalid Uri :" + aName);
+ }
+ iFileUtility = new FileUtility(actual);
+ iFinalizer = registerFinalize();
+ iIsOpen = true;
+ iMode = aMode;
+
+ FileLogger.Log("FileConnectionImpl: Connector.open succeeded");
+ }
+
+ /**
+ * Registers with Finalizer to call a method when the object gets collected
+ * by GC
+ *
+ * @return Finalizer object that will be notified when GC happens
+ */
+ private Finalizer registerFinalize()
+ {
+ return new Finalizer()
+ {
+ public void finalizeImpl()
+ {
+ doFinalize();
+ }
+ };
+ }
+
+ /**
+ * Checks for already granted permissions and prompts the user if access is
+ * allowed to the particular path. Prompting is delegated to
+ * ApplicationUtils
+ *
+ * @param aAbsolutePath
+ * target to which the connection is currently open
+ * @param aMode
+ * can either be FileAccessHelper.INTENT_READ or
+ * FileAccessHelper.INTENT_WRITE
+ */
+ private static void checkSecurityPermission(String aAbsolutePath, int aMode)
+ {
+ ApplicationUtils appUtils = ApplicationUtils.getInstance();
+
+ String accessIntent = (aMode == Connector.READ) ? FileAccessHelper.INTENT_READ
+ : FileAccessHelper.INTENT_WRITE;
+
+ FileLogger.Log("FileConnectionImpl: Check Permission to "
+ + aAbsolutePath + " in " + accessIntent + " mode");
+
+ // Go ahead to prompt the user
+ if (Connector.READ_WRITE == aMode)
+ {
+ FileInternalPermission permission = new FileInternalPermission(
+ aAbsolutePath, FileAccessHelper.INTENT_READ);
+ appUtils.checkPermission(permission);
+
+ FileInternalPermission permission1 = new FileInternalPermission(
+ aAbsolutePath, FileAccessHelper.INTENT_WRITE);
+ appUtils.checkPermission(permission1);
+ }
+ else
+ {
+ FileInternalPermission permission = new FileInternalPermission(
+ aAbsolutePath, accessIntent);
+ appUtils.checkPermission(permission);
+ }
+ }
+
+ /**
+ * Checks access to a specified path given its absolute path and the mode in
+ * which the connection has been opened.
+ *
+ * @param aAbsolutePath
+ * path of the connection
+ * @param aMode
+ * mode in which the connection has been opened.
+ * @throws SecurityException
+ * in case access was allowed for the application for the given
+ * intent and target.
+ */
+ private static void checkAccess(String aAbsolutePath, int aMode)
+ {
+ checkAccess(aAbsolutePath, aMode, false);
+ }
+
+ /**
+ * Checks access to a specified path given its absolute path and the mode in
+ * which the connection has been opened.
+ *
+ * @param aAbsolutePath
+ * path of the connection
+ * @param aMode
+ * mode in which the connection has been opened.
+ * @param aIsOpening
+ * specifies if the access check is being made on a method that
+ * is considered as open operation (setFileConnection and
+ * Connector.open)
+ * @throws SecurityException
+ * in case access was allowed for the application for the given
+ * intent and target.
+ */
+ private static void checkAccess(String aAbsolutePath, int aMode,
+ boolean aIsOpening)
+ {
+ FileLogger.Log("FileConnectionImpl: Check Access to " + aAbsolutePath
+ + " in " + aMode + " mode");
+
+ String modeString;
+ switch (aMode)
+ {
+ case Connector.READ:
+ modeString = FileAccessHelper.INTENT_READ;
+ break;
+ case Connector.WRITE:
+ modeString = FileAccessHelper.INTENT_WRITE;
+ break;
+ default:
+ modeString = FileAccessHelper.INTENT_READ_WRITE;
+ }
+
+ if (!(FileAccessHelper.accessAllowed(aAbsolutePath, modeString,
+ FileSystemUtils.getProtectionDomain(), aIsOpening)))
+ {
+ // Access to the specified path not allowed.
+ // Throw Security Exception
+ throw new SecurityException("Permission denied: " + aAbsolutePath);
+ }
+ }
+
+ private synchronized void doFinalize()
+ {
+ iFileUtility = null;
+ }
+
+ public void close()
+ {
+ iIsOpen = false;
+ iFileUtility = null;
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public final void create() throws IOException
+ {
+ checkConnection();
+ checkConnectionMode(Connector.READ);
+
+ String domain = FileSystemUtils.getProtectionDomain();
+
+ // We need to check if we have access to base directory and not the file
+ // itself :-)
+ if (!FileAccessHelper.isCreateAllowedWithinDir(iFileUtility.getPath(),
+ domain))
+ {
+ throw new SecurityException("Permission denied: "
+ + iFileUtility.getAbsolutePath());
+ }
+
+ if (!iFileUtility.createNewFile())
+ {
+ FileLogger.WLog("FileConnectionImpl: File Creation failed. "
+ + "Throwing IOException");
+ throw new IOException("Unable to create file: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public final void rename(String aName) throws IOException
+ {
+ FileLogger.Log("FileConnectionImpl: rename(): " + aName);
+
+ checkConnection();
+ checkConnectionMode(Connector.READ);
+ checkAccess(iFileUtility.getAbsolutePath(), Connector.WRITE);
+
+ if (!iFileUtility.rename(aName))
+ {
+ FileLogger
+ .ELog("FileConnectionImpl: File rename failed. Throwing IOException");
+ throw new IOException("Unable to rename file or directory: "
+ + iFileUtility.getAbsolutePath());
+ }
+
+ String curUrl = iFileConnectionUrl.getUrl();
+ if (curUrl.endsWith("/"))
+ {
+ // Remove trailing "/"
+ curUrl = curUrl.substring(0, curUrl.length() - 1);
+ }
+ String newUrl = curUrl.substring(0, curUrl.lastIndexOf('/') + 1);
+ newUrl += iFileUtility.getName();
+
+ iFileConnectionUrl = new FileConnectionURL(newUrl);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public final void mkdir() throws IOException
+ {
+ checkConnection();
+ checkConnectionMode(Connector.READ);
+ checkAccess(iFileUtility.getAbsolutePath(), Connector.WRITE);
+
+ FileLogger.Log("FileConnectionImpl: mkdir(): "
+ + iFileUtility.getAbsolutePath());
+ if (!iFileUtility.mkdir())
+ {
+ FileLogger.WLog(" FileConnectionImpl: "
+ + "FileUtility was unable to create directory.");
+ throw new IOException("Unable to create directory: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public final void delete() throws IOException
+ {
+ checkConnection();
+ checkConnectionMode(Connector.READ);
+ checkAccess(iFileUtility.getAbsolutePath(), Connector.WRITE);
+
+ FileLogger.Log("FileConnectionImpl: delete(): "
+ + iFileUtility.getAbsolutePath());
+ try
+ {
+ if (!iFileUtility.delete())
+ {
+ FileLogger.WLog("FileConnectionImpl: Unable to delete file. "
+ + "Throwing IOException.");
+ throw new IOException("Unable to delete file or directory: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+ catch (SecurityException ex)
+ {
+ throw new IOException("Unable to delete file or directory: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public boolean exists()
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.exists();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public String getName()
+ {
+ String name = iFileConnectionUrl.getName();
+ if (name.equals(""))
+ {
+ return "";
+ }
+
+ if (iFileUtility.isDirectory())
+ {
+ name += "/";
+ }
+ else if (!iFileUtility.exists())
+ {
+ // If it does not exist, and of the initial url ended with "/"
+ // we must return with a trailing "/"
+ if (iInitialUrl.endsWith("/"))
+ {
+ name += "/";
+ }
+ }
+
+ return name;
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public String getPath()
+ {
+ String path = iFileConnectionUrl.getPath();
+ return path;
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public String getURL()
+ {
+ String ret = iFileConnectionUrl.getUrl();
+ if (iFileUtility.isDirectory())
+ {
+ if (!ret.endsWith("/"))
+ {
+ ret += "/";
+ }
+ }
+ else
+ {
+ if (iFileUtility.isFile())
+ {
+ if (ret.endsWith("/"))
+ {
+ ret = ret.substring(0, ret.length() - 1);
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ *
+ */
+ public boolean isOpen()
+ {
+ return iIsOpen;
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public boolean canRead()
+ {
+ // Access Check
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.canRead();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public boolean canWrite()
+ {
+ // Access Check
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+
+ if (Connector.READ == iMode)
+ {
+ return false;
+ }
+ return iFileUtility.canWrite();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public long lastModified()
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.lastModified();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public boolean isDirectory()
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.isDirectory();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public void setReadable(boolean aReadable) throws IOException
+ {
+ checkConnection();
+ checkAccess(iFileUtility.getAbsolutePath(), Connector.WRITE);
+ checkConnectionMode(Connector.READ);
+ iFileUtility.setReadable(aReadable);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public void setWritable(boolean aWritable) throws IOException
+ {
+ checkConnection();
+ checkAccess(iFileUtility.getAbsolutePath(), Connector.WRITE);
+ checkConnectionMode(Connector.READ);
+ iFileUtility.setWritable(aWritable);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public void setHidden(boolean aHidden) throws IOException
+ {
+ checkConnection();
+ checkAccess(iFileUtility.getAbsolutePath(), Connector.WRITE);
+ checkConnectionMode(Connector.READ);
+ iFileUtility.setHidden(aHidden);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public Enumeration list() throws IOException
+ {
+ return list("*", false);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public Enumeration list(String aFilter, boolean aIncludeHidden)
+ throws IOException
+ {
+ FileLogger.Log("+FileConnectionImpl: list()");
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+
+ String filter = aFilter;
+ filter = trimFilter(filter);
+ checkFilter(filter);
+
+ // Ask FileUtility to give a list of files depending on its hidden
+ // status.
+ String[] fileList = iFileUtility.listFileArray(aIncludeHidden);
+ Vector accessibleFileList = new Vector();
+ String parent = iFileUtility.getAbsolutePath();
+
+ if (!parent.endsWith("/"))
+ {
+ parent += "/";
+ }
+
+ String domain = FileSystemUtils.getProtectionDomain();
+
+ // Check if read access is allowed to all contents in the list.
+ boolean accessCheckNeeded = FileAccessHelper.isDirRestricted(parent);
+ boolean accessAllowed = true;
+
+ for (int index = 0; index < fileList.length; index++)
+ {
+ String fullPath = parent + fileList[index];
+
+ if (FileUtility.matchString(filter.toLowerCase(), fileList[index]))
+ {
+ // If it passes the filter, check if midlet has access.
+ // if check access is true, then accessAllowed is not checked.
+ if (accessCheckNeeded)
+ {
+ accessAllowed = FileAccessHelper.accessAllowed(fullPath,
+ FileConstants.INTENT_READ, domain, true);
+ }
+
+ if (accessAllowed)
+ {
+ accessibleFileList.addElement(fileList[index]);
+ }
+ }
+ }
+ return accessibleFileList.elements();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public void truncate(long aByteOffset) throws IOException
+ {
+ checkConnection();
+ checkConnectionMode(Connector.READ);
+ checkAccess(iFileUtility.getAbsolutePath(), Connector.WRITE);
+ iFileUtility.truncate(aByteOffset);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public final void setFileConnection(String aName) throws IOException
+ {
+ int result = 0;
+ checkConnection();
+
+ if (aName == null)
+ {
+ FileLogger.ELog("FileConnectionImpl: setFileConnection(null)");
+ throw new NullPointerException("Argument passed was null");
+ }
+
+ aName = aName.trim();
+ checkSetFileConnParam(aName);
+
+ if (aName.equals("."))
+ {
+ FileLogger.Log("FileConnectionImpl: Set FileConnection to current");
+ // already in current directory
+ return;
+ }
+
+ if (!iFileUtility.isDirectory())
+ {
+ if (iFileUtility.exists())
+ {
+ throw new IOException("Connection is not a directory: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ // Case where we move up a directory
+ if (aName.equals("..") || aName.equals("../"))
+ {
+ FileLogger.Log("FileConnectionImpl: Set FileConnection to parent");
+ FileLogger.Log(" Current target: "
+ + iFileUtility.getAbsolutePath());
+ FileLogger.Log(" Next target : " + iFileUtility.getPath());
+
+ String parent = iFileUtility.getPath();
+
+ FileUtility tempTarget;
+ try
+ {
+ // If no exception is thrown, its safe to set connection
+ tempTarget = new FileUtility(parent);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ FileLogger.WLog("FileConnectionImpl: setFileConnection: "
+ + "Unable to create new FileUtility object. "
+ + "Cannot set fileconnection to new target.");
+ throw new IOException(
+ "File name is invalid or not accessible: " + aName);
+ }
+ catch (Exception e)
+ {
+ throw new IOException(
+ "File name is invalid or not accessible: " + aName);
+ }
+
+ // See if access is allowed. True because setting to new target is
+ // as good as opening.
+ checkAccess(tempTarget.getAbsolutePath(), iMode, true);
+ checkSecurityPermission(tempTarget.getAbsolutePath(), iMode);
+
+ // if we reach here, it is fine :-)
+ iFileUtility = tempTarget;
+
+ String prevUrl = iFileConnectionUrl.getUrl();
+ if (prevUrl.endsWith("/"))
+ {
+ prevUrl = prevUrl.substring(0, prevUrl.length() - 1);
+ }
+
+ String newUrl = prevUrl.substring(0, prevUrl.lastIndexOf('/'));
+ FileLogger.Log("FileConnectionImpl: setFileConnection: "
+ + "Creating new FileConnectionURL With: " + newUrl);
+ iFileConnectionUrl = new FileConnectionURL(newUrl, false);
+ return;
+ }
+
+ if (!iFileUtility.exists())
+ {
+ throw new IOException("Current directory does not exist: "
+ + iFileUtility.getAbsolutePath());
+ }
+
+ FileLogger.Log("FileConnectionImpl: setFileConnection(): "
+ + " Setting FileConnectionUrl to: " + aName);
+
+ String newTarget = iFileUtility.getAbsolutePath() + aName;
+
+ FileLogger.Log("FileConnectionImpl: setFileConnection(): "
+ + " Creating FileUtility with " + newTarget);
+
+ FileUtility tempTarget = new FileUtility(newTarget);
+
+ if (!tempTarget.exists())
+ {
+ FileLogger.WLog("FileConnectionImpl: setFileConnection(): "
+ + " New Target does not exist: "
+ + tempTarget.getAbsolutePath());
+
+ throw new IllegalArgumentException(
+ "File name is invalid or not accessible: " + aName);
+ }
+
+ // See if access is allowed. True because setting to new target is
+ // as good as opening.
+ checkAccess(tempTarget.getAbsolutePath(), iMode, true);
+ checkSecurityPermission(tempTarget.getAbsolutePath(), iMode);
+
+ // If no exception is thrown, its safe to set connection
+ iFileUtility = tempTarget;
+
+ String prevUrl = iFileConnectionUrl.getUrl();
+ if (!prevUrl.endsWith("/"))
+ {
+ prevUrl += "/";
+ }
+ String newUrl = prevUrl + iFileUtility.getName();
+
+ FileLogger.Log("FileConnectionImpl: setFileConnection: "
+ + "Creating new FileConnectionURL With: " + newUrl);
+
+ iFileConnectionUrl = new FileConnectionURL(newUrl, false);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public boolean isHidden()
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.isHidden();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public long availableSize()
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.availableSize();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public long usedSize()
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.usedSize();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public long totalSize()
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.totalSize();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public long fileSize() throws IOException
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.fileSize();
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public long directorySize(boolean aIncludeSubDirs) throws IOException
+ {
+ checkConnection();
+ checkConnectionMode(Connector.WRITE);
+ return iFileUtility.directorySize(aIncludeSubDirs);
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public InputStream openInputStream() throws IOException
+ {
+ checkConnectionMode(Connector.WRITE);
+ if (!isOpen())
+ {
+ throw new IOException();
+ }
+
+ checkSecurityPermission(iFileUtility.getAbsolutePath(), Connector.READ);
+ try
+ {
+ return iFileUtility.openInputStream();
+ }
+ catch (SecurityException ex)
+ {
+ FileLogger.ELog("FileConnectionImpl: " + "openInputStream(): "
+ + " SecurityException Caught from FileUtility. "
+ + "Throwing IOException.");
+
+ throw new IOException("Unable to open InputStream: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public DataInputStream openDataInputStream() throws IOException
+ {
+ checkConnectionMode(Connector.WRITE);
+
+ if (!isOpen())
+ {
+ throw new IOException();
+ }
+
+ checkSecurityPermission(iFileUtility.getAbsolutePath(), Connector.READ);
+ try
+ {
+ return iFileUtility.openDataInputStream();
+ }
+ catch (SecurityException ex)
+ {
+ FileLogger.ELog("FileConnectionImpl: " + "openDataInputStream(): "
+ + " SecurityException Caught from FileUtility. "
+ + "Throwing IOException.");
+
+ throw new IOException("Unable to open DataInputStream: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Opens an Output Stream. If there an already open output stream,
+ * IOException is thrown. Open succeeds only in case the application has
+ * access to open the file in write mode.
+ */
+ public OutputStream openOutputStream() throws IOException
+ {
+ checkConnectionMode(Connector.READ);
+ if (!isOpen())
+ {
+ throw new IOException();
+ }
+
+ checkSecurityPermission(iFileUtility.getAbsolutePath(), Connector.WRITE);
+ try
+ {
+ return iFileUtility.openOutputStream();
+ }
+ catch (SecurityException ex)
+ {
+ FileLogger.ELog("FileConnectionImpl: " + "openOutputStream(): "
+ + " SecurityException Caught from FileUtility. "
+ + "Throwing IOException.");
+
+ throw new IOException("Unable to open OutputStream: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public DataOutputStream openDataOutputStream() throws IOException
+ {
+ checkConnectionMode(Connector.READ);
+
+ if (!isOpen())
+ throw new IOException();
+
+ checkSecurityPermission(iFileUtility.getAbsolutePath(), Connector.WRITE);
+ try
+ {
+ return iFileUtility.openDataOutputStream();
+ }
+ catch (SecurityException ex)
+ {
+ FileLogger.ELog("FileConnectionImpl: " + "openDataOutputStream(): "
+ + " SecurityException Caught from FileUtility."
+ + " Throwing IOException.");
+
+ throw new IOException("Unable to open DataOutputStream: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Please refer JSR 75 for more details.
+ */
+ public OutputStream openOutputStream(long aOffset) throws IOException
+ {
+ checkConnectionMode(Connector.READ);
+ if (!isOpen())
+ throw new IOException();
+
+ if (aOffset < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ checkSecurityPermission(iFileUtility.getAbsolutePath(), Connector.WRITE);
+ try
+ {
+ checkSecurityPermission(iFileUtility.getAbsolutePath(), iMode);
+ return iFileUtility.openOutputStream(aOffset);
+ }
+ catch (SecurityException ex)
+ {
+ FileLogger.ELog("FileConnectionImpl: "
+ + "openDataOutputStream(offset): "
+ + " SecurityException Caught from FileUtility."
+ + " Throwing IOException.");
+
+ throw new IOException("Unable to open OutputStream: "
+ + iFileUtility.getAbsolutePath());
+ }
+ }
+
+ /** * ----------------------------- HELPERS ----------------------------- */
+
+ /**
+ * If the filter contains escaped characters, it unescapes them.
+ *
+ * @param aFilter
+ * filter string passed to list method
+ * @return new string with unescaped characters
+ */
+ private static String trimFilter(String aFilter)
+ {
+ String filter;
+ // If the name contains escaped sequences, remove them: %20
+ filter = FileUTF8Handler.decode(aFilter);
+ filter = filter.trim();
+ return filter;
+ }
+
+ /**
+ * Checks to see if the filter given by the user is valid. Checks against
+ * special charaters that must not be in the filter string.
+ *
+ * @param aFilter
+ * parameter passed to list method.
+ * @throws IllegalArgumentException
+ * in case it contains a character that is not allowed to be in
+ * a filer.
+ */
+ private static void checkFilter(String aFilter)
+ {
+ if ((aFilter.indexOf('?') != -1) || (aFilter.indexOf(":") != -1)
+ || (aFilter.indexOf("/") != -1)
+ || (aFilter.indexOf("\\") != -1)
+ || (aFilter.indexOf("//") != -1)
+ || (aFilter.indexOf("|") != -1) || (aFilter.indexOf("<") != -1)
+ || (aFilter.indexOf(">") != -1))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Checks to see if the connection is open.
+ *
+ */
+ private void checkConnection()
+ {
+ if (!iIsOpen)
+ throw new ConnectionClosedException("Connection has been closed");
+ }
+
+ /**
+ * Checks to see if the mode given aMode matches with the mode of the
+ * Connection.
+ *
+ * @param aMode
+ * mode in which the connection must not be opened.
+ * @throws IllegalModeException
+ * in case the mode is invalid
+ */
+ private final void checkConnectionMode(int aMode)
+ throws IllegalModeException
+ {
+ if (iMode == aMode)
+ {
+ throw new IllegalModeException(
+ "Illegal mode for this operation call");
+ }
+ }
+
+ /**
+ * Checks for sanity of the name passed to setFileConnection method. It must
+ * not contain characters that are not allowed in file names. Also, it must
+ * not have any path separators in it. Will throw IllegalArgumentException
+ * if the name was found to be improper.
+ *
+ * @param aName
+ * name of file/directory to which the target needs to be renamed
+ * @throws IOException
+ * in case it contains any of invalid characters.
+ */
+ private void checkSetFileConnParam(String aName) throws IOException
+ {
+ String toCheck = aName;
+ if (toCheck.endsWith("/"))
+ {
+ toCheck = toCheck.substring(0, toCheck.length() - 1);
+ }
+
+ if (toCheck.indexOf('?') != -1 || (toCheck.indexOf('<') != -1)
+ || (toCheck.indexOf('<') != -1) || (toCheck.indexOf(':') != -1)
+ || (toCheck.indexOf('|') != -1))
+ {
+ throw new IOException("Invalid file or directory name");
+ }
+
+ if ((toCheck.indexOf('*') != -1) || (toCheck.indexOf("/") != -1)
+ || (toCheck.indexOf("\\") != -1))
+ {
+ throw new IllegalArgumentException(
+ "Argument passed has path specification");
+ }
+ }
+}