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.spi.project.ui.support;
043:
044: import java.util.Arrays;
045: import java.util.LinkedHashSet;
046: import java.util.Set;
047: import org.netbeans.modules.project.uiapi.ProjectOpenedTrampoline;
048: import org.netbeans.spi.project.LookupMerger;
049: import org.netbeans.spi.project.ui.PrivilegedTemplates;
050: import org.netbeans.spi.project.ui.ProjectOpenedHook;
051: import org.netbeans.spi.project.ui.RecommendedTemplates;
052: import org.openide.util.Lookup;
053:
054: /**
055: * Factory class for creation of {@link org.netbeans.spi.project.LookupMerger} instances.
056: * @author mkleint
057: * @since org.netbeans.modules.projectuiapi 1.19
058: */
059: public final class UILookupMergerSupport {
060:
061: /** Creates a new instance of LookupMergerSupport */
062: private UILookupMergerSupport() {
063: }
064:
065: /**
066: * Create a {@link org.netbeans.spi.project.LookupMerger} instance
067: * for {@link org.netbeans.spi.project.ui.RecommendedTemplates}. Allows to merge
068: * templates from multiple sources.
069: * @return instance to include in project lookup
070: */
071: public static LookupMerger<RecommendedTemplates> createRecommendedTemplatesMerger() {
072: return new RecommendedMerger();
073: }
074:
075: /**
076: * Create a {@link org.netbeans.spi.project.LookupMerger} instance
077: * for {@link org.netbeans.spi.project.ui.PrivilegedTemplates}. Allows to merge
078: * templates from multiple sources.
079: * @return instance to include in project lookup
080: */
081: public static LookupMerger<PrivilegedTemplates> createPrivilegedTemplatesMerger() {
082: return new PrivilegedMerger();
083: }
084:
085: /**
086: * Create a {@link org.netbeans.spi.project.LookupMerger} instance
087: * for {@link org.netbeans.spi.project.ui.ProjectOpenedHook}. The merger makes sure all registered
088: * <code>ProjectOpenedHook</code> instances are called and that the default instance is called first.
089: * @param defaultInstance - the default {@link org.netbeans.spi.project.ui.ProjectOpenedHook} instance or null if
090: * a default privileged instance is not required.
091: * @return instance to include in project lookup
092: * @since org.netbeans.modules.projectuiapi 1.24
093: */
094: public static LookupMerger<ProjectOpenedHook> createProjectOpenHookMerger(
095: ProjectOpenedHook defaultInstance) {
096: return new OpenMerger(defaultInstance);
097: }
098:
099: private static class PrivilegedMerger implements
100: LookupMerger<PrivilegedTemplates> {
101: public Class<PrivilegedTemplates> getMergeableClass() {
102: return PrivilegedTemplates.class;
103: }
104:
105: public PrivilegedTemplates merge(Lookup lookup) {
106: return new PrivilegedTemplatesImpl(lookup);
107: }
108: }
109:
110: private static class RecommendedMerger implements
111: LookupMerger<RecommendedTemplates> {
112:
113: public Class<RecommendedTemplates> getMergeableClass() {
114: return RecommendedTemplates.class;
115: }
116:
117: public RecommendedTemplates merge(Lookup lookup) {
118: return new RecommendedTemplatesImpl(lookup);
119: }
120: }
121:
122: private static class OpenMerger implements
123: LookupMerger<ProjectOpenedHook> {
124: private ProjectOpenedHook defaultInstance;
125:
126: OpenMerger(ProjectOpenedHook def) {
127: defaultInstance = def;
128: }
129:
130: public Class<ProjectOpenedHook> getMergeableClass() {
131: return ProjectOpenedHook.class;
132: }
133:
134: public ProjectOpenedHook merge(Lookup lookup) {
135: return new OpenHookImpl(defaultInstance, lookup);
136: }
137:
138: }
139:
140: private static class PrivilegedTemplatesImpl implements
141: PrivilegedTemplates {
142:
143: private Lookup lkp;
144:
145: public PrivilegedTemplatesImpl(Lookup lkp) {
146: this .lkp = lkp;
147: }
148:
149: public String[] getPrivilegedTemplates() {
150: Set<String> templates = new LinkedHashSet<String>();
151: for (PrivilegedTemplates pt : lkp
152: .lookupAll(PrivilegedTemplates.class)) {
153: String[] temp = pt.getPrivilegedTemplates();
154: if (temp == null) {
155: throw new IllegalStateException(
156: pt.getClass().getName()
157: + " returns null from getPrivilegedTemplates() method."); //NOI18N
158: }
159: templates.addAll(Arrays.asList(temp));
160: }
161: return templates.toArray(new String[templates.size()]);
162: }
163: }
164:
165: private static class RecommendedTemplatesImpl implements
166: RecommendedTemplates {
167:
168: private Lookup lkp;
169:
170: public RecommendedTemplatesImpl(Lookup lkp) {
171: this .lkp = lkp;
172: }
173:
174: public String[] getRecommendedTypes() {
175: Set<String> templates = new LinkedHashSet<String>();
176: for (RecommendedTemplates pt : lkp
177: .lookupAll(RecommendedTemplates.class)) {
178: String[] temp = pt.getRecommendedTypes();
179: if (temp == null) {
180: throw new IllegalStateException(
181: pt.getClass().getName()
182: + " returns null from getRecommendedTemplates() method."); //NOI18N
183: }
184: templates.addAll(Arrays.asList(temp));
185: }
186: return templates.toArray(new String[templates.size()]);
187: }
188:
189: }
190:
191: private static class OpenHookImpl extends ProjectOpenedHook {
192:
193: private ProjectOpenedHook defaultInstance;
194: private Lookup lkp;
195:
196: OpenHookImpl(ProjectOpenedHook def, Lookup lkp) {
197: defaultInstance = def;
198: this .lkp = lkp;
199: //shall we listen on ProjectOpenedHook instance changes in lookup and
200: // call close on the disappearing ones?
201: }
202:
203: protected void projectOpened() {
204: if (defaultInstance != null) {
205: ProjectOpenedTrampoline.DEFAULT
206: .projectOpened(defaultInstance);
207: }
208: for (ProjectOpenedHook poh : lkp
209: .lookupAll(ProjectOpenedHook.class)) {
210: // just to make sure..
211: if (poh != defaultInstance) {
212: ProjectOpenedTrampoline.DEFAULT.projectOpened(poh);
213: }
214: }
215: }
216:
217: protected void projectClosed() {
218: if (defaultInstance != null) {
219: ProjectOpenedTrampoline.DEFAULT
220: .projectClosed(defaultInstance);
221: }
222: for (ProjectOpenedHook poh : lkp
223: .lookupAll(ProjectOpenedHook.class)) {
224: // just to make sure..
225: if (poh != defaultInstance) {
226: ProjectOpenedTrampoline.DEFAULT.projectClosed(poh);
227: }
228: }
229: }
230:
231: }
232:
233: }
|