com.iw.plugins.spindle.util.lookup.TapestryLookup.java Source code

Java tutorial

Introduction

Here is the source code for com.iw.plugins.spindle.util.lookup.TapestryLookup.java

Source

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Spindle, an Eclipse Plugin for Tapestry.
 *
 * The Initial Developer of the Original Code is
 * Intelligent Works Incorporated.
 * Portions created by the Initial Developer are Copyright (C) 2002
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 * 
 *  glongman@intelligentworks.com
 *
 * ***** END LICENSE BLOCK ***** */
package com.iw.plugins.spindle.util.lookup;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JarEntryFile;

import com.iw.plugins.spindle.TapestryPlugin;
import com.iw.plugins.spindle.util.JarEntryFileFaker;

// does not stay up to date as time goes on!

public class TapestryLookup implements ILookupAcceptor {

    protected IPackageFragmentRoot[] fPackageFragmentRoots = null;

    protected HashMap fPackageFragments;

    protected IJavaProject project;

    protected IWorkspace workspace;

    private boolean initialized = false;

    protected ILookupAcceptor acceptor;

    private Collection seekExtensions;

    public TapestryLookup() {

        acceptor = new DefaultAcceptor();

    }

    public void configure(IJavaProject project, ILookupAcceptor acceptor) throws JavaModelException {
        if (acceptor == null) {
            throw new IllegalArgumentException("null acceptor");
        }
        this.acceptor = acceptor;
        configure(project);
    }

    public void configure(IJavaProject project) throws JavaModelException {
        seekExtensions = TapestryPlugin.getManagedExtensions();
        this.project = project;
        workspace = project.getJavaModel().getWorkspace();
        fPackageFragmentRoots = project.getAllPackageFragmentRoots();
        fPackageFragments = new HashMap();
        IPackageFragment[] frags = getPackageFragmentsInRoots(fPackageFragmentRoots, project);
        for (int i = 0; i < frags.length; i++) {
            IPackageFragment fragment = frags[i];
            IPackageFragment[] entry = (IPackageFragment[]) fPackageFragments.get(fragment.getElementName());
            if (entry == null) {
                entry = new IPackageFragment[1];
                entry[0] = fragment;
                fPackageFragments.put(fragment.getElementName(), entry);
            } else {
                IPackageFragment[] copy = new IPackageFragment[entry.length + 1];
                System.arraycopy(entry, 0, copy, 0, entry.length);
                copy[entry.length] = fragment;
                fPackageFragments.put(fragment.getElementName(), copy);
            }
        }
        initialized = true;
    }

    private IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots, IJavaProject project) {

        ArrayList frags = new ArrayList();
        for (int i = 0; i < roots.length; i++) {
            IPackageFragmentRoot root = roots[i];
            try {
                IJavaElement[] children = root.getChildren();

                int length = children.length;
                if (length == 0)
                    continue;
                if (children[0].getParent().getParent().equals(project)) {
                    for (int j = 0; j < length; j++) {
                        frags.add(children[j]);
                    }
                } else {
                    for (int j = 0; j < length; j++) {
                        frags.add(root.getPackageFragment(children[j].getElementName()));
                    }
                }
            } catch (JavaModelException e) {
                // do nothing
            }
        }
        IPackageFragment[] fragments = new IPackageFragment[frags.size()];
        frags.toArray(fragments);
        return fragments;
    }

    public IStorage[] findComponent(String tapestryPath) {

        return findComponent(tapestryPath, ACCEPT_COMPONENTS);

    }

    public IStorage[] findByTapestryPath(String tapestryPath, int acceptFlags) {
        if (!initialized) {
            throw new Error("not initialized");
        }
        acceptFlags |= FULL_TAPESTRY_PATH;
        StorageOnlyRequest request = new StorageOnlyRequest();
        findAllManaged(tapestryPath, false, request, acceptFlags);
        return request.getResults();

    }

    public IStorage[] findComponent(String tapestryPath, int acceptFlags) {
        acceptFlags |= ACCEPT_COMPONENTS;
        return findByTapestryPath(tapestryPath, acceptFlags);
    }

    public IStorage findDefaultLibrary() {
        return findByTapestryPath("/net/sf/tapestry/Framework.library", ACCEPT_LIBRARIES | FULL_TAPESTRY_PATH)[0];
    }

    public IStorage[] findPage(String tapestryPath) {
        return findByTapestryPath(tapestryPath, ACCEPT_PAGES);
    }

    public IStorage[] findApplication(String tapestryPath) {
        return findByTapestryPath(tapestryPath, ACCEPT_APPLICATIONS);
    }

    public IStorage[] findLibrary(String tapestryPath) {
        return findByTapestryPath(tapestryPath, ACCEPT_LIBRARIES);
    }

    public IStorage[] findHtmlFor(String tapestryPath) {

        String usePath = tapestryPath.substring(0, tapestryPath.lastIndexOf("."));
        usePath += ".html";

        return findByTapestryPath(usePath, ACCEPT_HTML);
    }

    public IResource findParentResource(IStorage storage) throws JavaModelException {
        if (storage instanceof IResource) {
            return (IResource) ((IResource) storage).getParent();
        }
        IPackageFragment fragment = findPackageFragment(storage);
        if (fragment == null) {
            return null;
        }
        return (IResource) fragment.getParent().getUnderlyingResource();
    }

    public IPackageFragment findPackageFragment(String tapestryPath) {

        IStorage[] found = findByTapestryPath(tapestryPath, ACCEPT_ANY);

        if (found != null && found.length != 0) {

            try {

                return findPackageFragment(found[0]);

            } catch (JavaModelException e) {
            }

        }

        return null;

    }

    public IPackageFragment findPackageFragment(IStorage storage) throws JavaModelException {
        if (storage instanceof JarEntryFileFaker) {
            storage = (IStorage) storage.getAdapter(IStorage.class);
        }
        if (storage instanceof IResource) {

            IPackageFragment result = (IPackageFragment) project
                    .findPackageFragment(((IResource) storage).getParent().getFullPath());

            if (result != null) {

                return result;

            }
        }
        for (int i = 0; i < fPackageFragmentRoots.length; i++) {
            boolean isBinary = fPackageFragmentRoots[i].getKind() == IPackageFragmentRoot.K_BINARY;
            Object[] children = null;
            try {
                children = fPackageFragmentRoots[i].getChildren();
                if (children == null) {
                    continue;
                }
                for (int j = 0; j < children.length; j++) {
                    IPackageFragment fragment = (IPackageFragment) children[j];

                    Object[] nonJavaResources = fragment.getNonJavaResources();

                    if (nonJavaResources.length == 0) {

                        nonJavaResources = getSourcePackageResources(fragment);

                    }

                    for (int k = 0; k < nonJavaResources.length; k++) {
                        if (nonJavaResources[k].equals(storage)) {
                            return fragment;
                        }
                    }
                }
            } catch (CoreException ex) {
                //do nothing
            }
        }
        return null;

    }

    public boolean projectContainsJarEntry(JarEntryFile jarFile) {
        if (!initialized) {
            throw new Error("not initialized");
        }
        for (int i = 0; i < fPackageFragmentRoots.length; i++) {
            IPackageFragmentRoot root = fPackageFragmentRoots[i];
            IJavaElement[] packages = null;
            try {
                packages = root.getChildren();
            } catch (JavaModelException npe) {
                continue; // the root is not present, continue;
            }
            if (packages != null) {
                Object[] jarFiles = null;
                for (int j = 0, packageCount = packages.length; j < packageCount; j++) {
                    IPackageFragment pkg = (IPackageFragment) packages[j];
                    try {
                        if (pkg.getKind() == IPackageFragmentRoot.K_SOURCE) {
                            continue;
                        }
                        jarFiles = pkg.getNonJavaResources();
                    } catch (JavaModelException npe) {
                        continue;
                    }
                    for (int k = 0; k < jarFiles.length; k++) {
                        JarEntryFile other = (JarEntryFile) jarFiles[k];
                        if (jarFile.equals(other)) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    public void findAllManaged(String prefix, boolean partialMatch, ILookupRequestor requestor) {

        findAllManaged(prefix, partialMatch, requestor, ACCEPT_ANY);

    }

    public void findAllManaged(String prefix, boolean partialMatch, ILookupRequestor requestor, int acceptFlags) {

        if (!initialized) {

            throw new Error("not initialized");

        }
        int count = fPackageFragmentRoots.length;

        for (int i = 0; i < count; i++) {

            if (requestor.isCancelled()) {

                return;

            }
            IPackageFragmentRoot root = fPackageFragmentRoots[i];
            IJavaElement[] packages = null;

            try {

                packages = root.getChildren();

            } catch (JavaModelException npe) {

                continue; // the root is not present, continue;

            }
            if (packages != null) {

                for (int j = 0, packageCount = packages.length; j < packageCount; j++) {

                    if (requestor.isCancelled()) {

                        return;

                    }
                    if (seek(prefix, (IPackageFragment) packages[j], partialMatch, acceptFlags, requestor)) {

                        return;

                    }
                }
            }
        }
        seekExtensions = null;
    }

    public void findAllX(String prefix, boolean partialMatch, int acceptFlags, ILookupRequestor requestor) {

        if (!initialized) {
            throw new Error("not initialized");
        }
        int count = fPackageFragmentRoots.length;
        for (int i = 0; i < count; i++) {
            if (requestor.isCancelled())
                return;
            IPackageFragmentRoot root = fPackageFragmentRoots[i];
            IJavaElement[] packages = null;
            try {
                packages = root.getChildren();
            } catch (JavaModelException npe) {
                continue; // the root is not present, continue;
            }
            if (packages != null) {
                for (int j = 0, packageCount = packages.length; j < packageCount; j++) {
                    if (requestor.isCancelled())
                        return;
                    if (seek(prefix, (IPackageFragment) packages[j], partialMatch, acceptFlags, requestor)) {
                        return;
                    }
                }
            }
        }

    }

    public boolean seek(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags,
            ILookupRequestor requestor) {

        if (!initialized) {
            throw new Error("not initialized");
        }
        boolean stopLooking = false;
        String matchName = partialMatch ? name.toLowerCase() : name;
        if (pkg == null) {
            findAllManaged(matchName, partialMatch, requestor, acceptFlags);
            return stopLooking;
        }
        IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();

        try {
            int packageFlavor = root.getKind();

            switch (packageFlavor) {
            case IPackageFragmentRoot.K_BINARY:
                if ((acceptFlags & WRITEABLE) != 0) {
                    break;
                }
                stopLooking = seekInBinaryPackage(matchName, pkg, partialMatch, acceptFlags, requestor);
                break;
            case IPackageFragmentRoot.K_SOURCE:
                stopLooking = seekInSourcePackage(matchName, pkg, partialMatch, acceptFlags, requestor);
                break;
            default:
                return stopLooking;
            }
        } catch (JavaModelException e) {
            return stopLooking;
        }
        return stopLooking;
    }

    protected boolean seekInBinaryPackage(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags,
            ILookupRequestor requestor) {

        Object[] jarFiles = null;
        try {
            jarFiles = pkg.getNonJavaResources();
        } catch (JavaModelException npe) {
            return false; // the package is not present
        }
        int length = jarFiles.length;
        for (int i = 0; i < length; i++) {
            if (requestor.isCancelled()) {
                return true;
            }

            JarEntryFile jarFile = null;
            try {
                jarFile = (JarEntryFile) jarFiles[i];
            } catch (ClassCastException ccex) {
                //skip it
                continue;
            }
            if (acceptAsTapestry(project, jarFile, acceptFlags)) {
                if ((acceptFlags & FULL_TAPESTRY_PATH) != 0) {
                    if (nameMatchesFull(name, pkg, jarFile.getFullPath())) {
                        requestor.accept((IStorage) jarFile, pkg);
                        return true;
                    }
                    continue;
                } else if (nameMatches(name, jarFile.getName(), partialMatch)) {
                    requestor.accept((IStorage) jarFile, pkg);
                }
            }
        }
        return false;
    }

    protected boolean seekInSourcePackage(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags,
            ILookupRequestor requestor) {

        Object[] files = null;
        try {

            files = getSourcePackageResources(pkg);

        } catch (CoreException npe) {
            return false; // the package is not present
        }

        if (files == null) {

            return false;

        }
        int length = files.length;

        for (int i = 0; i < length; i++) {
            if (requestor.isCancelled()) {
                return true;
            }
            IFile file = null;
            try {
                file = (IFile) files[i];
            } catch (ClassCastException ccex) {
                // skip it
                continue;
            }
            boolean acceptedAsTapestry = acceptAsTapestry(project, file, acceptFlags);
            if (acceptAsTapestry(project, file, acceptFlags)) {
                if ((acceptFlags & FULL_TAPESTRY_PATH) != 0) {
                    if (nameMatchesFull(name, pkg, file.getFullPath())) {
                        requestor.accept((IStorage) file, pkg);
                        return true;
                    }
                    continue;
                } else if (nameMatches(name, file.getName(), partialMatch)) {
                    requestor.accept((IStorage) file, pkg);
                }
            }
        }
        return false;
    }

    /**
     * Method getPackageResources.
     * @param pkg
     * @return Object[]
     */
    private Object[] getSourcePackageResources(IPackageFragment pkg) throws CoreException {

        Object[] result = new Object[0];

        if (!pkg.isDefaultPackage()) {

            result = pkg.getNonJavaResources();

        } else {

            IContainer container = (IContainer) pkg.getUnderlyingResource();

            if (container != null) {

                IResource[] members = container.members(false);

                ArrayList resultList = new ArrayList();

                for (int i = 0; i < members.length; i++) {

                    if (members[i] instanceof IFile) {

                        resultList.add(members[i]);

                    }

                    result = resultList.toArray();

                }
            }

        }
        return result;
    }

    protected boolean nameMatches(String candidate, String existing, boolean partialMatch) {
        if ("*".equals(candidate)) {
            return true;
        }
        String LHS = candidate;
        String RHS = existing.toLowerCase();
        int dot = existing.lastIndexOf(".");
        if (dot > 0) {
            RHS = RHS.substring(0, dot);
        }
        return partialMatch ? RHS.startsWith(LHS) : LHS.equals(RHS);
    }

    protected boolean nameMatchesFull(String candidate, IPackageFragment pkg, IPath path) {
        String LHS = candidate;
        String existingName = "/" + pkg.getElementName() + "/";
        existingName = existingName.replace('.', '/');
        String RHS = existingName + path.lastSegment();
        return LHS.equals(RHS);
    }

    public boolean acceptAsTapestry(IJavaProject jproject, IStorage s, int acceptFlags) {
        if (seekExtensions != null) {
            String extension = s.getFullPath().getFileExtension();
            boolean result = seekExtensions.contains(extension);

            if (result && (acceptFlags & ACCEPT_TAPESTRY_PROJECTS_ONLY) != 0 && s instanceof IResource) {

                try {

                    IProject thisProject = jproject.getProject();
                    IProject resourceProject = ((IResource) s).getProject();

                    if (!thisProject.equals(resourceProject)
                            || !resourceProject.hasNature(TapestryPlugin.NATURE_ID)) {

                        return false;
                    }
                } catch (CoreException e) {

                    return false;
                }
            }
            return result;
        }
        return acceptor.acceptAsTapestry(jproject, s, acceptFlags);
    }

    public static class StorageOnlyRequest implements ILookupRequestor {

        ArrayList result;

        /**
         * @see ITapestryLookupRequestor#isCancelled()
         */
        public boolean isCancelled() {
            return false;
        }

        /**
         * @see ITapestryLookupRequestor#accept(IStorage, IPackageFragment)
         */
        public boolean accept(IStorage storage, IPackageFragment frgament) {
            if (result == null) {
                result = new ArrayList();
            }
            result.add(storage);
            return true;
        }

        public IStorage[] getResults() {
            if (result == null) {
                return new IStorage[0];
            } else {
                return (IStorage[]) result.toArray(new IStorage[0]);
            }
        }
    }

    /**
     * Method createRequest.
     * @return StorageOnlyRequest
     */
    public static StorageOnlyRequest createRequest() {
        return new StorageOnlyRequest();
    }

}