All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.java.testrunner.JavaUtils Maven / Gradle / Ivy

/*
 * 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.
 */

package org.netbeans.modules.java.testrunner;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.java.queries.UnitTestForSourceQuery;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.api.project.SourceGroupModifier;
import org.netbeans.api.project.Sources;
import org.netbeans.modules.gsf.testrunner.api.TestCreatorProvider;
import org.netbeans.modules.gsf.testrunner.plugin.RootsProvider;
import org.netbeans.modules.java.testrunner.providers.JavaRootsProvider;
import org.openide.ErrorManager;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
import org.openide.util.Lookup;
import org.openide.util.Utilities;

/**
 *
 * @author  Marian Petras
 */
public final class JavaUtils {

    /** */
    private final Project project;
    /**  */
    private boolean sourceGroupsOnly = true;
    /**  */
    private SourceGroup[] javaSourceGroups;
    /**  */
    private Map sourcesToTestsMap;
    /**  */
    private Map foldersToSourceGroupsMap;
    /**
     * Since 8.1, "junit" library definition and junit-3.8.2 binaries were
     * removed. This property is saved in project.properties file once the
     * project problems are resolved by updating test dependency to JUnit 4.x.
     * The possible values are "3" or "4" to indicate JUnit 3.x or JUnit 4.x
     * style for the test case sceletons.
     */
    public static final String PROP_JUNIT_SELECTED_VERSION = "junit.selected.version";
    
    /**
     * 
     */
    public JavaUtils(Project project) {
        this.project = project;
    }
    
    /**
     * Check whether this implementation supports given FileObjects.
     *
     * @param activatedFOs FileObjects to check
     * @return {@code true} if this instance supports given FileObjects, {@code false} otherwise
     */
    public static boolean isSupportEnabled(Class lookupClass, FileObject[] activatedFOs) {
        if (activatedFOs.length == 0) {
            return false;
        }

        final FileObject firstFile = activatedFOs[0];
        Project p = FileOwnerQuery.getOwner(firstFile);
        if (p == null) {
            return false;
        }
        if(p.getLookup().lookup(lookupClass) == null) {
            return false;
        }
        
        final SourceGroup sourceGroup = findSourceGroup(firstFile);
        if (sourceGroup == null) {
            return false;
        }
        final FileObject rootFolder = sourceGroup.getRootFolder();
        if (UnitTestForSourceQuery.findUnitTests(rootFolder).length == 0) {
            return false;
        }

        /*
         * Now we know that source folder of the first file has a corresponding
         * test folder (possible non-existent).
         */
        if (activatedFOs.length == 1) {
            /* ... if there is just one file selected, it is all we need: */
            return true;
        }

        /*
         * ...for multiple files, we just check that all the selected files
         * have the same root folder:
         */
        for (int i = 1; i < activatedFOs.length; i++) {
            FileObject fileObj = activatedFOs[i];
            if (!FileUtil.isParentOf(rootFolder, fileObj)
                    || !sourceGroup.contains(fileObj)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Finds a Java source group the given file belongs to.
     * 
     * @param  file  {@literal FileObject} to find a {@literal SourceGroup} for
     * @return  the found {@literal SourceGroup}, or {@literal null} if the given
     *          file does not belong to any Java source group
     */
    private static SourceGroup findSourceGroup(FileObject file) {
        final Project project = FileOwnerQuery.getOwner(file);
        if (project == null) {
            return null;
        }

        Sources src = ProjectUtils.getSources(project);
        SourceGroup[] srcGrps = src.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
        for (SourceGroup srcGrp : srcGrps) {
            FileObject rootFolder = srcGrp.getRootFolder();
            if (((file == rootFolder) || FileUtil.isParentOf(rootFolder, file)) 
                    && srcGrp.contains(file)) {
                return srcGrp;
            }
        }
        return null;
    }
    
    /**
     * Finds SourceGroups where a test for the given class
     * can be created (so that it can be found by the projects infrastructure
     * when a test for the class is to be opened or run).
     *
     * @param fo FileObject to find Source and Test filenames for
     * @param isTestNG {@code true} if user wants to create TestNG test, {@code false} otherwise
     * @param isSelenium {@code true} if user wants to create Selenium test, {@code false} otherwise
     * @return  an array of Strings - the first one being the source class name
     *          and the second being the test class name.
     *          the returned array may be empty but not null
     */
    public static String[] getSourceAndTestClassNames(FileObject fo, boolean isTestNG, boolean isSelenium) {
        String[] result = {"", ""};
        ClassPath cp = ClassPath.getClassPath(fo, ClassPath.SOURCE);
        if (cp != null) {
            result[0] = cp.getResourceName(fo, '.', false);
            String suffix = "";
            if(isTestNG) {
                suffix = TestCreatorProvider.TESTNG_TEST_CLASS_SUFFIX;
            }
            if(isSelenium) {
                suffix = TestCreatorProvider.INTEGRATION_TEST_CLASS_SUFFIX;
            } else {
                suffix = suffix.concat(TestCreatorProvider.TEST_CLASS_SUFFIX);
            }
            result[1] = result[0].concat(suffix);
        }
        return result;
    }

    /**
     * Finds SourceGroups where a test for the given class
     * can be created (so that it can be found by the projects infrastructure
     * when a test for the class is to be opened or run).
     *
     * @param createdSourceRoots
     * @param  fileObject  FileObject to find target
     *                     SourceGroup(s) for
     * @return  an array of objects - each of them can be either
     *          a SourceGroup for a possible target folder
     *          or simply a FileObject representing a possible
     *          target folder (if SourceGroup) for the folder
     *          was not found);
     *          the returned array may be empty but not null
     */
    public static Object[] getTestSourceRoots(Collection createdSourceRoots, FileObject fileObject) {
        Object[] targetFolders = CommonTestUtil.getTestTargets(fileObject);
        if (targetFolders == null || targetFolders.length == 0) {
            Project owner = FileOwnerQuery.getOwner(fileObject);
            if (owner != null) {
                String type = "";
                String hint = "";
                Collection rootProviders = Lookup.getDefault().lookupAll(RootsProvider.class);
                for (RootsProvider rootProvider : rootProviders) {
                    if(rootProvider instanceof JavaRootsProvider) {
                        type = rootProvider.getSourceRootType();
                        hint = rootProvider.getProjectTestsHint();
                    }
                }
                final SourceGroup grp = SourceGroupModifier.createAssociatedSourceGroup(owner, findSourceGroup(fileObject), type, hint);
                if (grp != null) {
                    createdSourceRoots.add(grp);
                    targetFolders = CommonTestUtil.getTestTargets(fileObject);
                }
            }
        }
        return targetFolders;
    }
    
    /**  */
    static FileObject findTestsRoot(Project project) {
        final SourceGroup[] sourceGroups
                = new JavaUtils(project).getJavaSourceGroups();
        for (int i = 0; i < sourceGroups.length; i++) {
            FileObject root = sourceGroups[i].getRootFolder();
            if (root.getName().equals(JavaProjectConstants.SOURCES_TYPE_JAVA)) {
                return root;
            }
        }
        return null;
    }
    
    /** */
    static FileObject getPackageFolder(
            FileObject root,
            String pkgName) throws IOException {
        String relativePathName = pkgName.replace('.', '/');
        FileObject folder = root.getFileObject(relativePathName);
        if (folder == null) {
            folder = FileUtil.createFolder(root, relativePathName);
        }
        return folder;
    }
    
    /**
     * Identifies and collects SourceGroups and folders
     * of a given project which may serve as target folders for newly created
     * test classes.
     *
     * @param  project  project whose folders are to be checked
     * @param  sourceGroupsOnly  return only SourceGroups
     *                           - ignore target folders not having
     *                           a corresponding SourceGroup
     * @return  collection which may contain FileObjects
     *          or SourceGroups (or both);
     *          it may be empty but not null
     * @author  Marian Petras
     */
    static Collection getTestTargets(Project project,
                                     final boolean sourceGroupsOnly) {
        final JavaUtils utils = new JavaUtils(project);
        return utils.getTestTargets(sourceGroupsOnly);
    }

    /**
     * Identifies and collects root test folders of a given project.
     * 
     * @param  project  project whose test folders are to be found
     * @return  collection of found {@code FileObject}s, possibly empty
     *          (but not {@code null})
     */
    public static Collection getTestFolders(Project project) {
        return new JavaUtils(project).getTestFolders();
    }
    
    /**
     * Builds a map that containing relation between SourceGroups
     * and their respective test SourceGroups.
     * Each entry of the map contains a SourceGroup as a key
     * and an array of test SourceGroups returned by
     * UnitTestForSourceQuery for that SourceGroup
     * as a value. SourceGroups that have no test
     * SourceGroups assigned are omitted, i.e. the resulting
     * map does not contain entries that would have empty arrays as their
     * values.
     *
     * @param  project  project whose SourceGroups are to be
     *                  checked
     * @param  sourceGroupsOnly  return only SourceGroups
     *                           - ignore test folders not having
     *                           a corresponding SourceGroup
     * @return  created map - may be empty, may be unmodifiable
     *                        never null
     */
    static Map getSourcesToTestsMap(Project project,
                                    final boolean sourceGroupsOnly) {
        final JavaUtils utils = new JavaUtils(project);
        return utils.getSourcesToTestsMap(sourceGroupsOnly);
    }
    
    /**
     * 
     */
    Project getProject() {
        return project;
    }

    /**
     * Identifies and collects root test folders of the project.
     * 
     * @return  collection of found {@code FileObject}s
     *          - may be empty but never {@code null}
     */
    private Collection getTestFolders() {
        
        /*
         * Idea:
         * 1) Get all SourceGroups
         * 2) For each SourceGroup, ask UnitTestForSourceQuery for its related
         *    test SourceGroups
         */

        /* .) get all SourceGroups: */
        final SourceGroup[] sourceGroups = getJavaSourceGroups();
        if (sourceGroups.length == 0) {
            return Collections.emptyList();
        }

        List result = null;

        /* .) for each SourceGroup, ask for test root folders: */
        for (SourceGroup sourceGroup : sourceGroups) {
            FileObject srcFolder = sourceGroup.getRootFolder();
            FileObject[] tstFoldersRaw = getTestFoldersRaw(srcFolder);
            if (tstFoldersRaw.length == 0) {
                continue;
            }

            for (FileObject tstFolder : tstFoldersRaw) {
                if (tstFolder == null) {
                    continue;
                }

                if (result == null) {
                    result = new ArrayList(2);
                }
                if (!result.contains(tstFolder)) {
                    result.add(tstFolder);
                }
            }
        }

        /* .) pack the results: */
        if (result == null) {
            return Collections.emptyList();
        } else {
            assert !result.isEmpty();
            return (result.size() == 1)
                   ? Collections.singleton(result.get(0))
                   : result;
        }
    }

    /**
     * Identifies and collects SourceGroups and folders
     * which may serve as target folders for newly created test classes.
     *
     * @param  sourceGroupsOnly  return only SourceGroups
     *                           (skip target folders without matching
     *                           SourceGroup)
     * @return  collection which may contain FileObjects
     *          or SourceGroups (or both);
     *          it may be empty but not null
     * @see  #getTestTargets(Project, boolean)
     * @author  Marian Petras
     */
    private Collection getTestTargets(final boolean sourceGroupsOnly) {

        /*
         * Idea:
         * 1) Get all SourceGroups
         * 2) For each SourceGroup, ask UnitTestForSourceQuery for its related
         *    test SourceGroups
         *
         * Union of all SourceGroups returned by UnitTestForSourceQuery
         * are the test SourceGroups.
         */

        /* .) get all SourceGroups: */
        final SourceGroup[] sourceGroups = getJavaSourceGroups();
        if (sourceGroups.length == 0) {
            return Collections.emptyList();
        }

        /* .) */
        createFoldersToSourceGroupsMap(sourceGroups);
        Object testTargetsUnion[] = new Object[sourceGroups.length];
        int size = 0;
        for (int i = 0; i < sourceGroups.length; i++) {
            Object[] testTargets = getTestTargets(sourceGroups[i],
                                                  sourceGroupsOnly);
            size = merge(testTargets, testTargetsUnion, size);
        }

        if (size != testTargetsUnion.length) {
            testTargetsUnion = CommonTestUtil.skipNulls(testTargetsUnion, new Object[0]);
        }

        return Collections.unmodifiableCollection(
                      Arrays.asList(testTargetsUnion));
    }
    
    /**
     * 
     */
    Map getSourcesToTestsMap() {
        if (sourcesToTestsMap == null) {
            sourcesToTestsMap = createSourcesToTestsMap(sourceGroupsOnly);
        }
        return sourcesToTestsMap;
    }
    
    /**
     * 
     */
    Map getSourcesToTestsMap(final boolean sourceGroupsOnly) {
        if (sourceGroupsOnly != this.sourceGroupsOnly) {
            sourcesToTestsMap = null;
            this.sourceGroupsOnly = sourceGroupsOnly;
        }
        return getSourcesToTestsMap();
    }

    /**
     * Builds a map that containing relation between SourceGroups
     * and their respective test SourceGroups.
     * Each entry of the map contains a SourceGroup as a key
     * and an array of test SourceGroups returned by
     * UnitTestForSourceQuery for that SourceGroup
     * as a value. SourceGroups that have no test
     * SourceGroups assigned are omitted, i.e. the resulting
     * map does not contain entries that would have empty arrays as their
     * values.
     *
     * @param  sourceGroupsOnly  return only SourceGroups
     *                           - ignore test folders not having
     *                           a corresponding SourceGroup
     * @return  created map - may be empty, may be unmodifiable,
     *                        cannot be null
     */
    private Map createSourcesToTestsMap(final boolean sourceGroupsOnly) {
        
        /*
         * Idea:
         * 1) Get all SourceGroups
         * 2) For each SourceGroup, ask UnitTestForSourceQuery for its related
         *    test SourceGroups
         */

        /* .) get all SourceGroups: */
        final SourceGroup[] sourceGroups = getJavaSourceGroups();
        if (sourceGroups.length == 0) {
            return Collections.emptyMap();
        }

        /* .) get test SourceGroups for each SourceGroup: */
        createFoldersToSourceGroupsMap(sourceGroups);
        Object testTargetsUnion[] = new Object[sourceGroups.length];
        Map map;
        map = new HashMap(
                            (int) ((float) sourceGroups.length * 1.33f + 0.5f),
                            .75f);
        for (int i = 0; i < sourceGroups.length; i++) {
            Object[] testTargets = getTestTargets(sourceGroups[i],
                                                  sourceGroupsOnly);
            if (testTargets.length != 0) {
                map.put(sourceGroups[i], testTargets);
            }
        }
        if (map.isEmpty()) {
            return Collections.emptyMap();
        }
        if (map.size() == 1) {
            Map.Entry entry
                    = map.entrySet().iterator().next();
            return Collections.singletonMap(entry.getKey(), entry.getValue());
        }

        final int finalMapSize = map.size();
        if (finalMapSize >= (sourceGroups.length - 5)) {
            return map;
        }
        
        final Map targetMap;
        targetMap = new HashMap(
                                    (int) ((float) finalMapSize * 1.25f + .5f),
                                    .8f);
        targetMap.putAll(map);
        return targetMap;
    }

    /**
     * Merges a given set of FileObjects and
     * SourceGroups to the given target set (which may contain
     * same types of elements).
     * The source set (array) is not modified during merge. The target
     * set (array) is not modified otherwise than by adding (overwriting
     * nulls) elements from the source set or by replacing elements
     * with equivalent elements (i.e. pointing to the same folder). Elements are
     * always added after the last non-null element of the target
     * set. After the merge, it is guaranteed that all null
     * elements of the target array are located at the end. The above
     * constraints can only be fulfilled if parameter
     * currTargetSetSize is correct and if all null
     * elements of the target set are placed at the end of the array at the
     * moment this method is called. The target array must contain enough
     * null elements so that all elements to be added to the set
     * can fit.
     *
     * @param  setToAdd  elements to be added to the target set
     *                   - must not contain null elements
     * @param  targetSet  array to add elements to
     * @param  currTargetSetSize  current count of non-null elements in the
     *                            target set (null elements are
     *                            always at the end of the array)
     * @return  new size of the target set
     *          (number of non-null elements)
     */
    private static int merge(final Object[] setToAdd,
                             final Object[] targetSet,
                             final int currTargetSetSize) {
        if (setToAdd.length == 0) {
            return currTargetSetSize;
        }
        if (currTargetSetSize == 0) {
            System.arraycopy(setToAdd, 0, targetSet, 0, setToAdd.length);
            return setToAdd.length;
        }
        int targetSetSize = currTargetSetSize;
        toAdd:
        for (int i = 0; i < setToAdd.length; i++) {
            final Object objToAdd = setToAdd[i];
            for (int j = 0; j < targetSetSize; j++) {
                final Object chosen = chooseTarget(targetSet[j], objToAdd);
                if (chosen != null) {           //both point to the same folder
                    targetSet[j] = chosen;
                    continue toAdd;
                }
            }
            targetSet[targetSetSize++] = objToAdd;
        }
        return targetSetSize;
    }

    /**
     * Finds whether the given two objects defining a target folder are equal
     * or not and if so, suggests which one is preferred.
     * Each of the folder targets may be either a SourceGroup
     * object or a FileObject folder. If both targets point
     * to the same folder, one of them which is preferred is returned.
     * Otherwise null is returned.
     * 

* If both targets are SourceGroups, the first target is used. * If none of the targets is a SourceGroup, the first target is * used. * Otherwise (i.e. one target is a SourceGroup, * the other is not), the SourceGroup target is returned. * * @param target1 one target * @param target2 second target * @return null if the two targets define different folders; * or the preferred one (of the passed targets) if the two * are equal */ private static Object chooseTarget(Object target1, Object target2) { final boolean isGroup1 = target1 instanceof SourceGroup; final boolean isGroup2 = target2 instanceof SourceGroup; assert isGroup1 || (target1 instanceof FileObject); assert isGroup2 || (target2 instanceof FileObject); if (isGroup1 && isGroup2 && target1.equals(target2)) { return target1; } final FileObject folder1 = isGroup1 ? ((SourceGroup) target1).getRootFolder() : ((FileObject) target1); final FileObject folder2 = isGroup2 ? ((SourceGroup) target2).getRootFolder() : ((FileObject) target2); if (!(folder1.isFolder())) { throw new IllegalArgumentException("target1: not a folder");//NOI18N } if (!(folder2.isFolder())) { throw new IllegalArgumentException("target2: not a folder");//NOI18N } if (folder1.equals(folder2)) { return (isGroup1 == isGroup2) ? target1 : (isGroup1 ? target1 : target2); } return null; } /** * Returns test targets for the given SourceGroup. * The test targets are folders which are searched when tests for a class * from the SourceGroup are to be found. Each of the returned * test targets may be either SourceGroup (representing * a folder plus additional information such as display name) or simply * a FileObject representing a folder. * If parameter includeSourceGroups is false, * only SourceGroups are returned (target folders without * corresponding SourceGroups are ignored). * * @param src source group to find test targets for * @param sourceGroupsOnly skip target folders without matching * SourceGroup * @return array which may contain FileObjects * or SourceGroups (or both); * it may be empty but not null * @see CommonTestUtil#getFileObject2SourceGroupMap */ public Object[] getTestTargets(SourceGroup sourceGroup, final boolean sourceGroupsOnly) { /* .) find test root folders: */ final FileObject[] testFolders = getTestFoldersRaw(sourceGroup.getRootFolder()); if (testFolders.length == 0) { return new Object[0]; } /* .) find SourceGroups corresponding to the FileObjects: */ final Object[] targets = new Object[testFolders.length]; for (int i = 0; i < targets.length; i++) { final FileObject testFolder = testFolders[i]; if (testFolder == null) { continue; } Object srcGroup = foldersToSourceGroupsMap.get(testFolder); targets[i] = (srcGroup != null) ? srcGroup : sourceGroupsOnly ? null : testFolder; } return CommonTestUtil.skipNulls(targets, new Object[0]); } /** * Returns an array of test folders corresponding to the given source * folder - may contain nulls. * * @param srcFolder FileObject representing source code root, * for which test root folders should be found * @return array of FileObjects representing test root * folders, possibly with superfluous null elements * @see #getSourceFoldersRaw */ public FileObject[] getTestFoldersRaw(FileObject srcFolder) { return getFileObjects(UnitTestForSourceQuery.findUnitTests(srcFolder), true); } /** * Returns an array of source folders corresponding to the given test * folder - may contain nulls. * * @param srcFolder FileObject representing source code root, * for which source root folders should be found * @return array of FileObjects representing source root * folders, possibly with superfluous null elements * @see #getTestFoldersRaw */ public FileObject[] getSourceFoldersRaw(FileObject testFolder) { return getFileObjects(UnitTestForSourceQuery.findSources(testFolder), true); } /** * Returns FileObjects represented by the given URLs. * * @param rootURLs URLs representing FileObjects * @param srcToTest true if we are searching for test * folders, false if we are searching * for source folders - affects only text of warning * log messages * @return array of FileObjects representing source root * folders, possibly with superfluous null elements */ private FileObject[] getFileObjects(final URL[] rootURLs, final boolean srcToTest) { if (rootURLs.length == 0) { return new FileObject[0]; } FileObject[] sourceRoots = new FileObject[rootURLs.length]; for (int i = 0; i < rootURLs.length; i++) { if ((sourceRoots[i] = URLMapper.findFileObject(rootURLs[i])) == null) { final int severity = ErrorManager.INFORMATIONAL; if (ErrorManager.getDefault().isLoggable(severity)) { ErrorManager.getDefault().log( severity, (srcToTest ? "Test" : "Source") //NOI18N + " directory " + rootURLs[i] //NOI18N + " declared by project " //NOI18N + ProjectUtils.getInformation(project).getName() + " does not exist."); //NOI18N } continue; } Project sourceRootOwner = FileOwnerQuery.getOwner(sourceRoots[i]); if (!project.equals(sourceRootOwner)) { sourceRoots[i] = null; int severity = ErrorManager.INFORMATIONAL; if (ErrorManager.getDefault().isNotifiable(severity)) { ErrorManager.getDefault().notify( severity, new IllegalStateException( "Malformed project: Found test root (" + //NOI18N rootURLs[i] + ')' + ' ' + (sourceRootOwner == null ? "does not belong to any" //NOI18N : "belongs to a different") + //NOI18N " project.")); //NOI18N } continue; } } return sourceRoots; } /** */ public static FileObject[] skipNulls(final FileObject[] fileObjs) { if (fileObjs.length == 0) { return fileObjs; } int nullsCount = 0; for (int i = 0; i < fileObjs.length; i++) { if (fileObjs[i] == null) { nullsCount++; } } if (nullsCount == 0) { return fileObjs; } if (nullsCount == fileObjs.length) { return new FileObject[0]; } final FileObject[] fileObjsNew = new FileObject[fileObjs.length - nullsCount]; int index = 0, indexNew = 0; while (indexNew < fileObjsNew.length) { FileObject fileObj = fileObjs[index++]; if (fileObj != null) { fileObjsNew[indexNew++] = fileObj; } } return fileObjsNew; } /** * Creates a map mapping folders to source groups. * For a folder as a key, the map returns the source group having that * folder as a root. The created map is stored to variable * {@link #foldersToSourceGroupsMap}. * * @param sourceGroup source group to create a map from * @author Marian Petras */ private void createFoldersToSourceGroupsMap( final SourceGroup[] sourceGroups) { Map result; if (sourceGroups.length == 0) { result = Collections.emptyMap(); } else { result = new HashMap(2 * sourceGroups.length, .5f); for (SourceGroup sourceGroup : sourceGroups) { result.put(sourceGroup.getRootFolder(), sourceGroup); } } foldersToSourceGroupsMap = result; } /** * */ public SourceGroup[] getJavaSourceGroups() { if (javaSourceGroups == null) { // String type = ""; // Collection providers = Lookup.getDefault().lookupAll(RootsProvider.class); // for (RootsProvider provider : providers) { // type = provider.getSourceRootType(); // break; // } javaSourceGroups = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); } return javaSourceGroups; } /** * Finds a SourceGroup having the specified root folder. * If there are more SourceGroups matching, the first one * (according to the order of elements in the array) is returned. * * @param sourceGroups source groups to test * @param rootFolder root folder of a source group to be found * @return the found SourceGroup; * or null if no matching SourceGroup * was found */ private static SourceGroup findSourceGroup(SourceGroup[] sourceGroups, FileObject rootFolder) { for (int i = 0; i < sourceGroups.length; i++) { if (sourceGroups[i].getRootFolder().equals(rootFolder)) { return sourceGroups[i]; } } return (SourceGroup) null; } static boolean isValidClassName(String className) { if (className.length() == 0) { return false; } char[] chars = className.toCharArray(); int segmentStart = 0; int i; for (i = 0; i < chars.length; i++) { if (chars[i] == '.') { if (i == segmentStart) { return false; //empty segment } if (!Utilities.isJavaIdentifier( className.substring(segmentStart, i))) { return false; //illegal name of the segment } segmentStart = i + 1; } } if (i == segmentStart) { return false; //empty last segment } if (!Utilities.isJavaIdentifier( className.substring(segmentStart, chars.length))) { return false; //illegal name of the last segment } return true; } }