| /* |
| * 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.spi.java.project.support; |
| |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.beans.PropertyChangeSupport; |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.EnumSet; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.atomic.AtomicInteger; |
| import org.netbeans.api.java.classpath.ClassPath; |
| import org.netbeans.junit.NbTestCase; |
| import org.netbeans.spi.java.classpath.ClassPathFactory; |
| import org.netbeans.spi.java.classpath.ClassPathImplementation; |
| import org.netbeans.spi.java.classpath.ClassPathProvider; |
| import org.netbeans.spi.java.classpath.FlaggedClassPathImplementation; |
| import org.netbeans.spi.java.classpath.PathResourceImplementation; |
| import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.util.Lookup; |
| import org.openide.util.lookup.AbstractLookup; |
| import org.openide.util.lookup.InstanceContent; |
| |
| /** |
| * |
| * @author mkleint |
| */ |
| public class ClassPathProviderMergerTest extends NbTestCase { |
| |
| public ClassPathProviderMergerTest(String testName) { |
| super(testName); |
| } |
| |
| /** |
| * Test of merge method, of class ClassPathProviderMerger. |
| */ |
| public void testMerge() { |
| InstanceContent ic = new InstanceContent(); |
| Lookup lookup = new AbstractLookup(ic); |
| ProviderImpl defaultCP = new ProviderImpl(); |
| //for some weird reason the specific path doesn't work in this module. |
| // it worked fine in Java Support APIs module before moving here |
| // URL url = createURLReference("org/netbeans/modules/java/project/"); |
| URL url = createURLReference(""); |
| defaultCP.paths.put(ClassPath.COMPILE, ClassPathSupport.createClassPath(url)); |
| ClassPathProviderMerger instance = new ClassPathProviderMerger(defaultCP); |
| ClassPathProvider result = instance.merge(lookup); |
| ClassPath cp = result.findClassPath(null, ClassPath.BOOT); |
| assertNull(cp); |
| |
| ClassPath compile = result.findClassPath(null, ClassPath.COMPILE); |
| assertNotNull(compile); |
| FileObject[] fos = compile.getRoots(); |
| assertNotNull(fos); |
| assertEquals(1, fos.length); |
| |
| final AtomicInteger count = new AtomicInteger(); |
| compile.addPropertyChangeListener(new PropertyChangeListener() { |
| public void propertyChange(PropertyChangeEvent evt) { |
| final String propName = evt.getPropertyName(); |
| if (ClassPath.PROP_ENTRIES.equals(propName) || |
| ClassPath.PROP_ROOTS.equals(propName)) { |
| count.incrementAndGet(); |
| } |
| } |
| }); |
| |
| ProviderImpl additional = new ProviderImpl(); |
| //for some weird reason the specific path doesn't work in this module. |
| // it worked fine in Java Support APIs module before moving here |
| // additional.paths.put(ClassPath.COMPILE, ClassPathSupport.createClassPath(createURLReference("org/netbeans/spi/java/project/classpath/"))); |
| // additional.paths.put(ClassPath.BOOT, ClassPathSupport.createClassPath(createURLReference("org/netbeans/spi/java/project/support/"))); |
| additional.paths.put(ClassPath.COMPILE, ClassPathSupport.createClassPath(createURLReference(""))); |
| additional.paths.put(ClassPath.BOOT, ClassPathSupport.createClassPath(createURLReference(""))); |
| |
| ic.add(additional); |
| |
| fos = compile.getRoots(); |
| assertNotNull(fos); |
| assertEquals(2, fos.length); |
| assertEquals(2, count.get()); // why 2 changes are fired? |
| |
| cp = result.findClassPath(null, ClassPath.COMPILE); |
| assertEquals(cp, compile); |
| |
| cp = result.findClassPath(null, ClassPath.BOOT); |
| assertNotNull(cp); |
| fos = cp.getRoots(); |
| assertNotNull(fos); |
| assertEquals(fos.length, 1); |
| |
| |
| ic.remove(additional); |
| |
| fos = compile.getRoots(); |
| assertNotNull(fos); |
| assertEquals(1, fos.length); |
| assertEquals(4, count.get()); // why 2 changes are fired? |
| |
| |
| } |
| |
| public void testMissingEvents() throws Exception { |
| InstanceContent ic = new InstanceContent(); |
| Lookup lookup = new AbstractLookup(ic); |
| ProviderImpl defaultCP = new ProviderImpl(); |
| |
| final URL root1 = FileUtil.urlForArchiveOrDir(FileUtil.normalizeFile(new File(getWorkDir(),"root1"))); |
| final URL root2 = FileUtil.urlForArchiveOrDir(FileUtil.normalizeFile(new File(getWorkDir(),"root2"))); |
| final MutableCPImpl cpImpl = new MutableCPImpl(root1); |
| |
| defaultCP.paths.put(ClassPath.COMPILE, ClassPathFactory.createClassPath(cpImpl)); |
| ClassPathProviderMerger instance = new ClassPathProviderMerger(defaultCP); |
| ClassPathProvider result = instance.merge(lookup); |
| |
| ClassPath compile = result.findClassPath(null, ClassPath.COMPILE); |
| assertNotNull(compile); |
| assertEquals(1, compile.entries().size()); |
| |
| cpImpl.add(root2); |
| assertEquals(2, compile.entries().size()); |
| } |
| |
| public final void testPropagatesFlags() throws IOException { |
| InstanceContent ic = new InstanceContent(); |
| Lookup lookup = new AbstractLookup(ic); |
| final URL root1 = FileUtil.urlForArchiveOrDir(FileUtil.normalizeFile(new File(getWorkDir(),"root1"))); |
| final URL root2 = FileUtil.urlForArchiveOrDir(FileUtil.normalizeFile(new File(getWorkDir(),"root2"))); |
| |
| ProviderImpl defaultCP = new ProviderImpl(); |
| final MutableCPImpl cpImpl = new MutableCPImpl(root1); |
| defaultCP.paths.put(ClassPath.COMPILE, ClassPathFactory.createClassPath(cpImpl)); |
| ClassPathProviderMerger instance = new ClassPathProviderMerger(defaultCP); |
| ClassPathProvider result = instance.merge(lookup); |
| |
| ClassPath compile = result.findClassPath(null, ClassPath.COMPILE); |
| assertNotNull(compile); |
| assertEquals(0, compile.getFlags().size()); |
| |
| final ProviderImpl additional = new ProviderImpl(); |
| final MutableCPImpl addCpImpl = new MutableCPImpl(root2); |
| addCpImpl.add(ClassPath.Flag.INCOMPLETE); |
| additional.paths.put(ClassPath.COMPILE, ClassPathFactory.createClassPath(addCpImpl)); |
| ic.add(additional); |
| |
| assertEquals(1, compile.getFlags().size()); |
| assertSame(compile, result.findClassPath(null, ClassPath.COMPILE)); |
| |
| addCpImpl.remove(ClassPath.Flag.INCOMPLETE); |
| assertEquals(0, compile.getFlags().size()); |
| addCpImpl.add(ClassPath.Flag.INCOMPLETE); |
| assertEquals(1, compile.getFlags().size()); |
| } |
| |
| public void testFlagsEvents() throws Exception { |
| InstanceContent ic = new InstanceContent(); |
| Lookup lookup = new AbstractLookup(ic); |
| final URL root1 = FileUtil.urlForArchiveOrDir(FileUtil.normalizeFile(new File(getWorkDir(),"root1"))); |
| final URL root2 = FileUtil.urlForArchiveOrDir(FileUtil.normalizeFile(new File(getWorkDir(),"root2"))); |
| |
| ProviderImpl defaultCP = new ProviderImpl(); |
| final MutableCPImpl cpImpl = new MutableCPImpl(root1); |
| defaultCP.paths.put(ClassPath.COMPILE, ClassPathFactory.createClassPath(cpImpl)); |
| ClassPathProviderMerger instance = new ClassPathProviderMerger(defaultCP); |
| ClassPathProvider result = instance.merge(lookup); |
| |
| ClassPath compile = result.findClassPath(null, ClassPath.COMPILE); |
| assertNotNull(compile); |
| |
| final AtomicInteger count = new AtomicInteger(); |
| compile.addPropertyChangeListener((evt) -> { |
| if (ClassPath.PROP_FLAGS.equals(evt.getPropertyName())) { |
| count.incrementAndGet(); |
| } |
| }); |
| final ProviderImpl additional = new ProviderImpl(); |
| final MutableCPImpl addCpImpl = new MutableCPImpl(root2); |
| addCpImpl.add(ClassPath.Flag.INCOMPLETE); |
| additional.paths.put(ClassPath.COMPILE, ClassPathFactory.createClassPath(addCpImpl)); |
| ic.add(additional); |
| assertEquals(1, count.get()); |
| count.set(0); |
| addCpImpl.remove(ClassPath.Flag.INCOMPLETE); |
| assertEquals(1, count.get()); |
| count.set(0); |
| addCpImpl.add(ClassPath.Flag.INCOMPLETE); |
| assertEquals(1, count.get()); |
| count.set(0); |
| } |
| |
| private static URL createURLReference(String path) { |
| URL url = ClassPathProviderMergerTest.class.getClassLoader().getResource(path); |
| |
| return url; |
| } |
| |
| private class ProviderImpl implements ClassPathProvider { |
| |
| public Map<String, ClassPath> paths = new HashMap<String, ClassPath>(); |
| |
| public ClassPath findClassPath(FileObject file, String type) { |
| return paths.get(type); |
| } |
| |
| } |
| |
| private static final class MutableCPImpl implements FlaggedClassPathImplementation { |
| private final List<PathResourceImplementation> roots; |
| private final Set<ClassPath.Flag> flags; |
| private final PropertyChangeSupport support; |
| |
| |
| MutableCPImpl(URL... urls) { |
| roots = new ArrayList<>(); |
| flags = EnumSet.noneOf(ClassPath.Flag.class); |
| this.support = new PropertyChangeSupport(this); |
| add(urls); |
| } |
| |
| void add(ClassPath.Flag... flgs) { |
| for (ClassPath.Flag flg : flgs) { |
| flags.add(flg); |
| } |
| support.firePropertyChange(PROP_FLAGS, null, null); |
| } |
| |
| void remove(ClassPath.Flag... flgs) { |
| for (ClassPath.Flag flg : flgs) { |
| flags.remove(flg); |
| } |
| support.firePropertyChange(PROP_FLAGS, null, null); |
| } |
| |
| void add(URL... urls) { |
| for (URL url : urls) { |
| roots.add(ClassPathSupport.createResource(url)); |
| } |
| support.firePropertyChange(PROP_RESOURCES, null, null); |
| } |
| |
| @Override |
| public List<? extends PathResourceImplementation> getResources() { |
| return roots; |
| } |
| |
| @Override |
| public Set<ClassPath.Flag> getFlags() { |
| return this.flags; |
| } |
| |
| @Override |
| public void addPropertyChangeListener(PropertyChangeListener listener) { |
| support.addPropertyChangeListener(listener); |
| } |
| |
| @Override |
| public void removePropertyChangeListener(PropertyChangeListener listener) { |
| support.removePropertyChangeListener(listener); |
| } |
| |
| } |
| |
| } |
| |