Package org.apache.harmony.x.swing.filechooser.windows

Source Code of org.apache.harmony.x.swing.filechooser.windows.WinFileManager$ItemIdProcessor

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

/**
* @author Anton Avtamonov, Rustem Rafikov
* @version $Revision$
*/
package org.apache.harmony.x.swing.filechooser.windows;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import org.apache.harmony.awt.nativebridge.Int16Pointer;
import org.apache.harmony.awt.nativebridge.Int32Pointer;
import org.apache.harmony.awt.nativebridge.Int8Pointer;
import org.apache.harmony.awt.nativebridge.NativeBridge;
import org.apache.harmony.awt.nativebridge.PointerPointer;
import org.apache.harmony.awt.nativebridge.windows.Win32;
import org.apache.harmony.awt.nativebridge.windows.WindowsDefs;
import org.apache.harmony.awt.nativebridge.windows.WindowsConsts;
import org.apache.harmony.x.swing.filechooser.PlatformFile;
import org.apache.harmony.x.swing.filechooser.PlatformFileManager;

import org.apache.harmony.x.swing.internal.nls.Messages;

public class WinFileManager implements PlatformFileManager {

    private static WinFileManager instance;

    private static final Win32 win32 = Win32.getInstance();
    private static final NativeBridge nb = NativeBridge.getInstance();

    //  REFIID for IShellFolder interface, see ComDefs.h
    public static final Win32.GUID SHELL_FOLDER_GUID = getGUID("{000214E6-0000-0000-C000-000000000046}");

    private final Win32.IShellFolder DESKTOP_SHELL_FOLDER = createDesktopShellFolder();
    private final WinFile DESKTOP_FOLDER = getWinFile(getAbsoluteItemID(WindowsDefs.CSIDL_DESKTOP));

    public static WinFileManager getManager() {
        return instance;
    }

    public WinFileManager() {
        if (instance != null) {
            throw new RuntimeException(Messages.getString("swing.6C")); //$NON-NLS-1$
        }
        instance = this;
    }

    public File getDefaultFolder() {
        return getMyDocumentsFolder();
    }

    public File getHomeFolder() {
        return getDesktopFolder();
    }

    public PlatformFile getPlatformFile(final File file) {
        if (file instanceof WinFile) {
            return (WinFile)file;
        }

        Win32.ITEMIDLIST absoluteItemId = getAbsoluteItemID(file
                .getAbsolutePath());
        if (absoluteItemId == null) {
            return null;
        }

        return getWinFile(absoluteItemId);
    }

    public WinFile getDesktopFolder() {
        return DESKTOP_FOLDER;
    }

    public Win32.IShellFolder getDesktopShellFolder() {
        return DESKTOP_SHELL_FOLDER;
    }

    public WinFile getMyDocumentsFolder() {
        return getWinFileForSystemFolder(WindowsDefs.CSIDL_PERSONAL);
    }

    public WinFile[] getDrives() {
        WinFile myComputer = getWinFileForSystemFolder(WindowsDefs.CSIDL_DRIVES);
        if (myComputer != null) {
            List drives = myComputer.getContent(WindowsConsts.SHCONTF_STORAGE);
            return (WinFile[]) drives.toArray(new WinFile[drives.size()]);
        }

        return new WinFile[0];
    }

    Win32.ITEMIDLIST[] getShellContent(final Win32.ITEMIDLIST absoluteParentItemId, final int flags) {
        Win32.IShellFolder parentFolder = getShellFolder(absoluteParentItemId);
        List result = new LinkedList();
        PointerPointer enumIDListPtrPtr = nb.createPointerPointer(1, false);
        if (parentFolder.EnumObjects(0, flags, enumIDListPtrPtr) == WindowsDefs.NOERROR) {
            Win32.IEnumIDList idList = win32.createIEnumIDList(enumIDListPtrPtr.getAddress(0));

            PointerPointer itemListPtr = nb.createPointerPointer(1, false);

            while (true) {
                if (idList.Next(1, itemListPtr, null) == WindowsDefs.NOERROR) {
                    Win32.ITEMIDLIST itemId = win32.createITEMIDLIST(itemListPtr.getAddress(0));
                    result.add(ItemIdProcessor.getAbsoluteItemID(absoluteParentItemId, itemId));
                } else {
                    break;
                }
            }
            idList.Release();
        }
        release(parentFolder);

        return (Win32.ITEMIDLIST[])result.toArray(new Win32.ITEMIDLIST[result.size()]);
    }

    WinFile getWinFile(final Win32.ITEMIDLIST absoluteItemId) {
        Object[] parentInfo = getParentShellInfo(absoluteItemId);
        Win32.IShellFolder parentFolder = (Win32.IShellFolder)parentInfo[0];
        String path = getPath(parentFolder, (Win32.ITEMIDLIST)parentInfo[1]);
        release(parentFolder);

        return new WinFile(path, absoluteItemId);
    }

    String getChildFolderDisplayName(final Win32.IShellFolder parent, final Win32.ITEMIDLIST itemId, final int flags) {
        int bufLen = 2048;

        Win32.STRRET strret = win32.createSTRRET(false);

        if (parent.GetDisplayNameOf(itemId, flags, strret) != WindowsDefs.NOERROR) {
            return null;
        }

        Int16Pointer bufPtr = nb.createInt16Pointer(bufLen, false);
        win32.StrRetToBufW(strret, null, bufPtr, bufLen);
        return bufPtr.getString();
    }

    void release(final Win32.IShellFolder folder) {
        if (folder == null) {
            return;
        }
        folder.Release();
    }

    int getAttribute(final Win32.IShellFolder parent, final Win32.ITEMIDLIST itemId, final int flags) {
        PointerPointer itemIdPtrPtr = nb.createPointerPointer(1, false);
        itemIdPtrPtr.set(0, itemId);

        Int32Pointer resultPtr = nb.createInt32Pointer(1, false);
        resultPtr.set(0, flags);
        if (parent.GetAttributesOf(1, itemIdPtrPtr, resultPtr) != WindowsDefs.NOERROR) {
            return -1;
        }
        return resultPtr.get(0);
    }

    Win32.SHFILEINFOW getFileInfo(final Win32.ITEMIDLIST itemId, final int flags) {
        Win32.SHFILEINFOW fileInfo = win32.createSHFILEINFOW(false);

        Win32.SHFILEINFOW result = null;
        if (win32.SHGetFileInfoW(nb.createInt16Pointer(itemId), 0, fileInfo,
                fileInfo.size(), WindowsDefs.SHGFI_PIDL | flags) != 0) {
            result = fileInfo;
        }
        return result;
    }

    int getDescription(final Win32.IShellFolder parent, final Win32.ITEMIDLIST itemId) {
        Win32.SHDESCRIPTIONID res = win32.createSHDESCRIPTIONID(false);

        if (win32.SHGetDataFromIDListW(parent, itemId, WindowsDefs.SHGDFIL_DESCRIPTIONID, res, res.size()) == WindowsDefs.NOERROR) {
            return res.get_dwDescriptionId();
        }
        return 0 ;
    }

    Win32.ITEMIDLIST getParentItemId(final Win32.ITEMIDLIST absoluteItemId) {
        return ItemIdProcessor.getAbsoluteParentItemID(absoluteItemId);
    }

    Object[] getParentShellInfo(final Win32.ITEMIDLIST absoluteItemId) {

        PointerPointer relativeItemIdPrtPrt = nb.createPointerPointer(1, false);
        PointerPointer shellFolderPtrPtr = nb.createPointerPointer(1, false);
        if (win32.SHBindToParent(absoluteItemId, WinFileManager.SHELL_FOLDER_GUID, shellFolderPtrPtr,
                relativeItemIdPrtPrt) != WindowsDefs.NOERROR) {
            return new Object[2];
        }
        Win32.IShellFolder parentFolder = win32.createIShellFolder(shellFolderPtrPtr.getAddress(0));
        Win32.ITEMIDLIST relativeItemId = win32.createITEMIDLIST(relativeItemIdPrtPrt.getAddress(0));
        return new Object[] { parentFolder, relativeItemId };
    }

    private String getPath(final Win32.IShellFolder parent, final Win32.ITEMIDLIST itemId) {
        return getChildFolderDisplayName(parent, itemId, WindowsConsts.SHGDN_FORPARSING);
    }

    private static Win32.GUID getGUID(final String name) {
        Int16Pointer namePrt = nb.createInt16Pointer(name, false);
        Win32.GUID result = win32.createGUID(false);
        if (win32.CLSIDFromString(namePrt, result) != WindowsDefs.NOERROR) {
            return null;
        }
        return result;
    }

    private Win32.IShellFolder getShellFolder(final Win32.ITEMIDLIST absoluteItemId) {
        if (ItemIdProcessor.isRoot(absoluteItemId)) {
            return getDesktopShellFolder();
        }

        Object[] parentInfo = getParentShellInfo(absoluteItemId);
        Win32.IShellFolder parentFolder = (Win32.IShellFolder)parentInfo[0];
        Win32.IShellFolder result = getShellFolder(parentFolder, (Win32.ITEMIDLIST)parentInfo[1]);
        release(parentFolder);

        return result;
    }

    private Win32.IShellFolder getShellFolder(final Win32.IShellFolder parent, final Win32.ITEMIDLIST itemId) {
        if (parent == null) {
            return null;
        }

        PointerPointer childPtrPtr = nb.createPointerPointer(1, false);
        if (parent.BindToObject(itemId, null, WinFileManager.SHELL_FOLDER_GUID, childPtrPtr) != WindowsDefs.NOERROR) {
            return null;
        }
        return win32.createIShellFolder(childPtrPtr.getAddress(0));
    }

    private WinFile getWinFileForSystemFolder(final int folderID) {
        Win32.ITEMIDLIST itemId = getAbsoluteItemID(folderID);
        if (itemId != null) {
            return getWinFile(itemId);
        }
        return null;
    }

    private Win32.IShellFolder createDesktopShellFolder() {
        PointerPointer shellDesktopPtrPtr = nb.createPointerPointer(1, false);
        if (win32.SHGetDesktopFolder(shellDesktopPtrPtr) != WindowsDefs.NOERROR) {
            return null;
        }
        return win32.createIShellFolder(shellDesktopPtrPtr.getAddress(0));
    }

    private Win32.ITEMIDLIST getAbsoluteItemID(final int folderId) {
        PointerPointer itemIdPtrPtr = nb.createPointerPointer(1, false);
        if (win32.SHGetFolderLocation(0, folderId, null, 0, itemIdPtrPtr) != WindowsDefs.NOERROR) {
            return null;
        }
        return win32.createITEMIDLIST(itemIdPtrPtr.getAddress(0));
    }

    private Win32.ITEMIDLIST getAbsoluteItemID(final String path) {
        Win32.IShellFolder desktop = getDesktopShellFolder();

        Int16Pointer displayNamePtr = nb.createInt16Pointer(path, false);
        PointerPointer itemIdPtrPtr = nb.createPointerPointer(1, false);
        if (desktop.ParseDisplayName(0, null, displayNamePtr, null, itemIdPtrPtr, null) != WindowsDefs.NOERROR) {
            return null;
        }
        return win32.createITEMIDLIST(itemIdPtrPtr.getAddress(0));
    }

    private static class ItemIdProcessor {
        public static Win32.ITEMIDLIST getAbsoluteItemID(final Win32.ITEMIDLIST parentAbsoluteItemId, final Win32.ITEMIDLIST itemId) {
            final int parentSize = getItemIDListSize(parentAbsoluteItemId) - 2;
            if (parentSize <= 0) {
                return itemId;
            }
            final int childSize = getItemIDListSize(itemId);
            Int8Pointer resPtr = nb.createInt8Pointer(parentSize + childSize, true); //!!! should be in native mem

            resPtr.copy(parentAbsoluteItemId, 0, parentSize);
            resPtr.copy(itemId, parentSize, childSize);

            return win32.createITEMIDLIST(resPtr);
        }

        public static Win32.ITEMIDLIST getAbsoluteParentItemID(final Win32.ITEMIDLIST absoluteItemId) {
            Win32.ITEMIDLIST lastItemId = getLastItemIDList(absoluteItemId);
            if (lastItemId == null) {
                return null;
            }

            final int parentSize = (int)(lastItemId.shortLockPointer() - absoluteItemId.shortLockPointer());
            lastItemId.unlock();
            absoluteItemId.unlock();

            Int8Pointer resPtr = nb.createInt8Pointer(parentSize + 2, true); // !!! should be in native mem
            resPtr.copy(absoluteItemId, 0, parentSize);
            resPtr.copy(lastItemId.getElementPointer(getItemIDListSize(lastItemId) - 2), parentSize, 2);
            return win32.createITEMIDLIST(resPtr);
        }

        public static boolean isRoot(final Win32.ITEMIDLIST itemId) {
            return getFirstItemSize(itemId) == 0;
        }

        private static int getFirstItemSize(final Win32.ITEMIDLIST itemId) {
            return itemId.get_mkid().get_cb();
        }

        private static Win32.ITEMIDLIST getNextItemID(final Win32.ITEMIDLIST itemId) {
            if (itemId == null) {
                return null;
            }
            final int size = getFirstItemSize(itemId);
            if (size == 0) {
                return null;
            }

            Win32.ITEMIDLIST result = win32.createITEMIDLIST(itemId.getElementPointer(size));

            final int nextSize = getFirstItemSize(result);
            if (nextSize == 0) {
                return null;
            }
            return result;
        }

        private static int getItemIDListSize(final Win32.ITEMIDLIST itemId) {
            int size = getFirstItemSize(itemId);
            if (size == 0) {
                return 0;
            }

            Win32.ITEMIDLIST child = getNextItemID(itemId);
            while (child != null) {
                size += getFirstItemSize(child);
                child = getNextItemID(child);
            }
            return size + 2;
        }

        private static Win32.ITEMIDLIST getLastItemIDList(final Win32.ITEMIDLIST itemId) {
            if (getFirstItemSize(itemId) == 0) {
                return null;
            }

            Win32.ITEMIDLIST prevChild = itemId;
            Win32.ITEMIDLIST child = getNextItemID(prevChild);
            while (child != null) {
                prevChild = child;
                child = getNextItemID(child);
            }

            return prevChild;
        }
    }
}
TOP

Related Classes of org.apache.harmony.x.swing.filechooser.windows.WinFileManager$ItemIdProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.