001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.project.ui.actions;
043:
044: import java.lang.ref.WeakReference;
045: import java.util.Arrays;
046: import java.util.Collections;
047: import java.util.HashSet;
048: import java.util.Set;
049: import junit.framework.AssertionFailedError;
050: import org.netbeans.api.project.Project;
051: import org.netbeans.junit.NbTestCase;
052: import org.openide.filesystems.FileObject;
053: import org.openide.util.Lookup;
054: import org.openide.util.lookup.Lookups;
055: import org.openide.util.lookup.ProxyLookup;
056:
057: /**
058: *
059: * @author Jan Lahoda
060: */
061: public class ActionsUtilTest extends NbTestCase {
062:
063: public ActionsUtilTest(String testName) {
064: super (testName);
065: }
066:
067: protected void setUp() throws Exception {
068: }
069:
070: //due to use of weak references in ActionsUtil.LookupResultsCache this test fails
071: //(there are cache misses after GC, and there may be even cache miss during the
072: //first "assertTrue(result == ActionsUtil.getProjectsFromLookup(projects, null))"
073: //statement.
074: // public void testCacheWorks() throws Exception {
075: // Project prj1 = new DummyProject();
076: // Project prj2 = new DummyProject();
077: // Lookup projects = Lookups.fixed(new Object[] {
078: // prj1, prj2,
079: // });
080: //
081: // Project[] result = ActionsUtil.getProjectsFromLookup(projects, null);
082: //
083: // assertTrue(result == ActionsUtil.getProjectsFromLookup(projects, null));
084: //
085: // //make sure the cache lives as long as the projects lookup:
086: // //try hard to force gc:
087: // for (int i = 0; i < 5; i++) {
088: // System.gc();
089: // System.runFinalization();
090: // }
091: //
092: // assertTrue(result == ActionsUtil.getProjectsFromLookup(projects, null));
093: // }
094:
095: private static final Object o = new Object();
096:
097: public void testCacheUpdatesCorrectly() throws Exception {
098: Project prj1 = new DummyProject();
099: Project prj2 = new DummyProject();
100: TestProxyLookup projects = new TestProxyLookup(new Lookup[] {
101: prj1.getLookup(), prj2.getLookup(), });
102:
103: Set<Project> bothProjects = new HashSet<Project>(Arrays.asList(
104: prj1, prj2));
105: Set<Project> result = new HashSet<Project>(Arrays
106: .asList(ActionsUtil.getProjectsFromLookup(projects,
107: null)));
108:
109: assertTrue(bothProjects.equals(result));
110:
111: //make sure cache is somehow updated even after hard GC:
112: //and try really hard to reclaim even (potential) SoftReferences:
113: boolean wasThrown = false;
114:
115: try {
116: assertGC("", new WeakReference<Object>(o));
117: } catch (AssertionFailedError e) {
118: //ignore
119: wasThrown = true;
120: }
121:
122: assertTrue(wasThrown);
123:
124: projects.setLookupsOverride(new Lookup[] { prj1.getLookup() });
125:
126: Set<Project> firstProject = new HashSet<Project>(Arrays
127: .asList(prj1));
128:
129: result = new HashSet<Project>(Arrays.asList(ActionsUtil
130: .getProjectsFromLookup(projects, null)));
131:
132: assertTrue(firstProject.equals(result));
133:
134: projects.setLookupsOverride(new Lookup[] {});
135:
136: result = new HashSet<Project>(Arrays.asList(ActionsUtil
137: .getProjectsFromLookup(projects, null)));
138:
139: assertTrue(Collections.EMPTY_SET.equals(result));
140:
141: projects.setLookupsOverride(new Lookup[] { prj1.getLookup(),
142: prj2.getLookup() });
143:
144: result = new HashSet<Project>(Arrays.asList(ActionsUtil
145: .getProjectsFromLookup(projects, null)));
146:
147: assertTrue(bothProjects.equals(result));
148: }
149:
150: public void testCanBeReclaimed() throws Exception {
151: Project prj1 = new DummyProject();
152: Project prj2 = new DummyProject();
153: Lookup projects = new TestProxyLookup(new Lookup[] {
154: prj1.getLookup(), prj2.getLookup(), });
155:
156: ActionsUtil.getProjectsFromLookup(projects, null);
157:
158: WeakReference<?> ref1 = new WeakReference<Object>(prj1);
159: WeakReference<?> ref2 = new WeakReference<Object>(prj2);
160: WeakReference<?> lookup = new WeakReference<Object>(projects);
161:
162: prj1 = null;
163: prj2 = null;
164: projects = null;
165:
166: assertGC("the projects can be reclaimed", ref1);
167: assertGC("the projects can be reclaimed", ref2);
168: assertGC("the lookup can be reclaimed", lookup);
169: }
170:
171: public void testCanBeReclaimedWithSimpleLookup() throws Exception {
172: Project prj1 = new DummyProject();
173: Project prj2 = new DummyProject();
174: Lookup projects = Lookups.fixed(new Object[] { prj1, prj2, });
175:
176: ActionsUtil.getProjectsFromLookup(projects, null);
177:
178: WeakReference<?> ref1 = new WeakReference<Object>(prj1);
179: WeakReference<?> ref2 = new WeakReference<Object>(prj2);
180: WeakReference<?> lookup = new WeakReference<Object>(projects);
181:
182: prj1 = null;
183: prj2 = null;
184: projects = null;
185:
186: assertGC("the projects can be reclaimed", ref1);
187: assertGC("the projects can be reclaimed", ref2);
188: assertGC("the lookup can be reclaimed", lookup);
189: }
190:
191: private static final class TestProxyLookup extends ProxyLookup {
192:
193: public TestProxyLookup(Lookup[] lookups) {
194: super (lookups);
195: }
196:
197: public void setLookupsOverride(Lookup[] lookups) {
198: setLookups(lookups);
199: }
200:
201: }
202:
203: private static final class DummyProject implements Project {
204:
205: private final Lookup lookup = Lookups.singleton(this );
206:
207: public FileObject getProjectDirectory() {
208: return null;
209: }
210:
211: public Lookup getLookup() {
212: return lookup;
213: }
214:
215: }
216:
217: }
|